CINXE.COM

community/contributors/devel/sig-architecture/api-conventions.md at master · kubernetes/community · GitHub

<!DOCTYPE html> <html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system" data-a11y-link-underlines="true" > <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> <link rel="preconnect" href="https://github.githubassets.com" crossorigin> <link rel="preconnect" href="https://avatars.githubusercontent.com"> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-7aa84bb7e11e.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-f65db3e8d171.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-a8258e3c6dda.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-7e97d834719c.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-01d869f460be.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-534f3e971240.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-a8cc7d138001.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-35e9dfdc4f9f.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-cf4cc5f62dfe.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-d9abecd14f1e.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-93aded0ee8a1.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-8bed0685a4b5.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-a954a02d9269.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-4fce88777fa8.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-0210be90f4d3.css" /> <script type="application/json" id="client-env">{"locale":"en","featureFlags":["bypass_copilot_indexing_quota","copilot_immersive_file_preview","copilot_new_references_ui","copilot_attach_folder_reference","copilot_personal_instructions","copilot_personal_instructions_templates","copilot_chat_repo_custom_instructions_preview","copilot_chat_retry_on_error","copilot_chat_persist_submitted_input","copilot_conversational_ux_history_refs","copilot_chat_shared_chat_input","copilot_chat_shared_topic_indicator","copilot_chat_shared_repo_sso_banner","copilot_editor_upsells","copilot_dotcom_chat_reduce_telemetry","copilot_implicit_context","copilot_no_floating_button","copilot_smell_icebreaker_ux","copilot_read_shared_conversation","dotcom_chat_client_side_skills","experimentation_azure_variant_endpoint","failbot_handle_non_errors","geojson_azure_maps","ghost_pilot_confidence_truncation_25","ghost_pilot_confidence_truncation_40","github_models_o3_mini_streaming","hovercard_accessibility","issues_react_remove_placeholders","issues_react_blur_item_picker_on_close","issues_react_include_bots_in_pickers","marketing_pages_search_explore_provider","remove_child_patch","sample_network_conn_type","swp_enterprise_contact_form","site_copilot_vscode_link_update","site_proxima_australia_update","issues_react_create_milestone","issues_react_cache_fix_workaround","lifecycle_label_name_updates"]}</script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/wp-runtime-d9b48e2a0f05.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover_js-9da652f58479.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_arianotify-polyfill_ariaNotify-polyfill_js-node_modules_github_mi-3abb8f-d7e6bc799724.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_failbot_failbot_ts-4600dbf2d60a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/environment-f04cb2a9fc8c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_primer_behaviors_dist_esm_index_mjs-0dbb79f97f8f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_selector-observer_dist_index_esm_js-f690fd9ae3d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_relative-time-element_dist_index_js-f6da4b3fa34c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_auto-complete-element_dist_index_js-node_modules_github_catalyst_-8e9f78-a74b4e0a8a6b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_text-expander-element_dist_index_js-78748950cb0c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-b5f1d7-a1760ffda83d.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_markdown-toolbar-element_dist_index_js-ceef33f593fa.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_primer_view-co-c44a69-f0c8a795d1fd.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/github-elements-44d18ad044b3.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/element-registry-682f1551aebf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_braintree_browser-detection_dist_browser-detection_js-node_modules_githu-2906d7-2a07a295af40.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lit-html_lit-html_js-be8cb88f481b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_morphdom_dist_morphdom-e-7c534c-a4a1922eb55f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_turbo_dist_turbo_es2017-esm_js-e3cbe28f1638.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-893f9f-6cf3320416b8.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_color-convert_index_js-e3180fe3bcb3.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_quote-selection_dist_index_js-node_modules_github_session-resume_-947061-205cd97df772.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_updatable-content_updatable-content_ts-a1563f62660e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_task-list_ts-app_assets_modules_github_sso_ts-ui_packages-900dde-f48a418a99d4.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_sticky-scroll-into-view_ts-8fa27fd7fbb6.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_ajax-error_ts-app_assets_modules_github_behaviors_include-87a4ae-e2caa5390f5a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_commenting_edit_ts-app_assets_modules_github_behaviors_ht-83c235-783fc7e142e5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/behaviors-44598a9103f2.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_catalyst_lib_index_js-f6223d90c7ba.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-global-e12489347ccf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_github_catalyst_lib_inde-dbbea9-26cce2010167.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/code-menu-6a5f60eab447.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/primer-react-8e38c0ecf8b7.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-core-4128f7c95445.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-lib-f1bca44e0926.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/octicons-react-611691cca2f6.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_emotion_is-prop-valid_dist_emotion-is-prop-valid_esm_js-node_modules_emo-62da9f-2df2f32ec596.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_stacktrace-parser_dist_s-e7dcdd-f7cc96ebae76.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover-fn_js-55fea94174bf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_dompurify_dist_purify_js-b89b98661809.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lodash-es__Stack_js-node_modules_lodash-es__Uint8Array_js-node_modules_l-4faaa6-4a736fde5c2f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lodash-es__baseIsEqual_js-8929eb9718d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_hydro-analytics-client_dist_analytics-client_js-node_modules_gith-853b24-f2006d2a5b98.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_focus-visible_dist_focus-visible_js-node_modules_fzy_js_index_js-node_mo-35e85b-b2842e98946f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_aria-live_aria-live_ts-ui_packages_promise-with-resolvers-polyfill_promise-with-r-17c672-d6b5ea82572a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_paths_index_ts-9c4436ef49de.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ref-selector_RefSelector_tsx-2cce17df147b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_diffs_diff-parts_ts-555a13945c12.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_code-view-shared_utilities_web-worker_ts-ui_packages_code-view-shared_worker-jobs-f6d1fe-f58a463eaa8e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_code-view-shared_hooks_use-canonical-object_ts-ui_packages_code-view-shared_hooks-a6859a-09c7f754ea79.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_repos-file-tree-view_repos-file-tree-view_ts-ui_packages_feature-request_FeatureR-648c3b-e2701dc83e0b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_blob-anchor_ts-ui_packages_code-nav_code-nav_ts-ui_packages_filter--8253c1-91468a3354f9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-code-view-32a132bb540c.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.0afb134baf4ff545faf9.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-code-view.ab7d8fac328c00e5e0cc.module.css" /> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-eff84ecbf2b6.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.0afb134baf4ff545faf9.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.1bcff9205c241e99cff2.module.css" /> <title>community/contributors/devel/sig-architecture/api-conventions.md at master · kubernetes/community · GitHub</title> <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient> <meta name="route-controller" content="blob" data-turbo-transient> <meta name="route-action" content="show" data-turbo-transient> <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb"> <meta name="request-id" content="D77C:24CA77:16DD41:1E4E22:67B51528" data-pjax-transient="true"/><meta name="html-safe-nonce" content="2e31e9a0be4ad4edd7aca409bd905fb8ad6b4d63e865012ece8fe797942ea1d7" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENzdDOjI0Q0E3NzoxNkRENDE6MUU0RTIyOjY3QjUxNTI4IiwidmlzaXRvcl9pZCI6IjY1NDY5ODU4MTU0NTQ4NDgyOTYiLCJyZWdpb25fZWRnZSI6InNvdXRoZWFzdGFzaWEiLCJyZWdpb25fcmVuZGVyIjoic291dGhlYXN0YXNpYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="444e1cfcb35f9f83c12e431e3e5a5404ff5928e7114494de5ba8f88bf3cc3fd6" data-pjax-transient="true"/> <meta name="hovercard-subject-tag" content="repository:57939112" data-turbo-transient> <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" /> <meta name="selected-link" value="repo_source" data-turbo-transient> <link rel="assets" href="https://github.githubassets.com/"> <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I"> <meta name="octolytics-url" content="https://collector.github.com/github/collect" /> <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" /> <meta name="user-login" content=""> <meta name="viewport" content="width=device-width"> <meta name="description" content="Kubernetes community content. Contribute to kubernetes/community development by creating an account on GitHub."> <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> <meta property="fb:app_id" content="1401488693436528"> <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md" /> <meta name="twitter:image" content="https://opengraph.githubassets.com/245ad2a7921900eb2f74429db57e2dc1c9287243129c17840ee71a87a9ed9673/kubernetes/community" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="community/contributors/devel/sig-architecture/api-conventions.md at master · kubernetes/community" /><meta name="twitter:description" content="Kubernetes community content. Contribute to kubernetes/community development by creating an account on GitHub." /> <meta property="og:image" content="https://opengraph.githubassets.com/245ad2a7921900eb2f74429db57e2dc1c9287243129c17840ee71a87a9ed9673/kubernetes/community" /><meta property="og:image:alt" content="Kubernetes community content. Contribute to kubernetes/community development by creating an account on GitHub." /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="community/contributors/devel/sig-architecture/api-conventions.md at master · kubernetes/community" /><meta property="og:url" content="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md" /><meta property="og:description" content="Kubernetes community content. Contribute to kubernetes/community development by creating an account on GitHub." /> <meta name="hostname" content="github.com"> <meta name="expected-hostname" content="github.com"> <meta http-equiv="x-pjax-version" content="d9c9fb2bc35639abd7280e32b622164a5d64d7063d1681212d407872bd0ce550" data-turbo-track="reload"> <meta http-equiv="x-pjax-csp-version" content="ace39c3b6632770952207593607e6e0be0db363435a8b877b1f96abe6430f345" data-turbo-track="reload"> <meta http-equiv="x-pjax-css-version" content="1c71206221e00a0a8e77d94d48d954f34ddbd711c4a0ced954fd49cd786cfa61" data-turbo-track="reload"> <meta http-equiv="x-pjax-js-version" content="8d0944c13eb1f3c7d8573e6cb620e3ac36589ce05977f1a732b25a69d29aa85c" data-turbo-track="reload"> <meta name="turbo-cache-control" content="no-preview" data-turbo-transient=""> <meta name="turbo-cache-control" content="no-cache" data-turbo-transient> <meta data-hydrostats="publish"> <meta name="go-import" content="github.com/kubernetes/community git https://github.com/kubernetes/community.git"> <meta name="octolytics-dimension-user_id" content="13629408" /><meta name="octolytics-dimension-user_login" content="kubernetes" /><meta name="octolytics-dimension-repository_id" content="57939112" /><meta name="octolytics-dimension-repository_nwo" content="kubernetes/community" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="57939112" /><meta name="octolytics-dimension-repository_network_root_nwo" content="kubernetes/community" /> <meta name="turbo-body-classes" content="logged-out env-production page-responsive"> <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000"> <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png"> <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon"> <meta name="theme-color" content="#1e2327"> <meta name="color-scheme" content="light dark" /> <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials"> </head> <body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div class="position-relative header-wrapper js-header-wrapper "> <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a> <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full"> <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span> </span> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ui-commands_ui-commands_ts-e571874765ef.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-765cf28766da.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.0afb134baf4ff545faf9.module.css" /> <react-partial partial-name="keyboard-shortcuts-dialog" data-ssr="false" data-attempted-ssr="false" > <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script> <div data-target="react-partial.reactRoot"></div> </react-partial> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-94fd67-73b675cf164a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/sessions-2d195d11c56b.js"></script> <header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark> <h2 class="sr-only">Navigation Menu</h2> <button type="button" class="HeaderMktg-backdrop d-lg-none border-0 position-fixed top-0 left-0 width-full height-full js-details-target" aria-label="Toggle navigation"> <span class="d-none">Toggle navigation</span> </button> <div class="d-flex flex-column flex-lg-row flex-items-center px-3 px-md-4 px-lg-5 height-full position-relative z-1"> <div class="d-flex flex-justify-between flex-items-center width-full width-lg-auto"> <div class="flex-1"> <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target js-nav-padding-recalculate js-header-menu-toggle Button--link Button--medium Button d-lg-none color-fg-inherit p-1"> <span class="Button-content"> <span class="Button-label"><div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div></span> </span> </button> </div> <a class="mr-lg-3 color-fg-inherit flex-order-2 js-prevent-focus-on-mobile-nav" href="/" aria-label="Homepage" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Logomark;ref_loc:Header&quot;}"> <svg height="32" aria-hidden="true" viewBox="0 0 24 24" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z"></path> </svg> </a> <div class="flex-1 flex-order-2 text-right"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fkubernetes%2Fcommunity%2Fblob%2Fmaster%2Fcontributors%2Fdevel%2Fsig-architecture%2Fapi-conventions.md" class="HeaderMenu-link HeaderMenu-button d-inline-flex d-lg-none flex-order-1 f5 no-underline border color-border-default rounded-2 px-2 py-1 color-fg-inherit js-prevent-focus-on-mobile-nav" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="86e9f362b1517270a3192b0a7ace0593167890241543f2eea734ecca93d771a4" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to Sign in&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}" > Sign in </a> </div> </div> <div class="HeaderMenu js-header-menu height-fit position-lg-relative d-lg-flex flex-column flex-auto top-0"> <div class="HeaderMenu-wrapper d-flex flex-column flex-self-start flex-lg-row flex-auto rounded rounded-lg-0"> <nav class="HeaderMenu-nav" aria-label="Global"> <ul class="d-lg-flex list-style-none"> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Product <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_copilot&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_copilot_link_product_navbar&quot;}" href="https://github.com/features/copilot"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">GitHub Copilot</div> Write better code with AI </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;security&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;security_link_product_navbar&quot;}" href="https://github.com/features/security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Security</div> Find and fix vulnerabilities </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;actions&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;actions_link_product_navbar&quot;}" href="https://github.com/features/actions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-workflow color-fg-subtle mr-3"> <path d="M1 3a2 2 0 0 1 2-2h6.5a2 2 0 0 1 2 2v6.5a2 2 0 0 1-2 2H7v4.063C7 16.355 7.644 17 8.438 17H12.5v-2.5a2 2 0 0 1 2-2H21a2 2 0 0 1 2 2V21a2 2 0 0 1-2 2h-6.5a2 2 0 0 1-2-2v-2.5H8.437A2.939 2.939 0 0 1 5.5 15.562V11.5H3a2 2 0 0 1-2-2Zm2-.5a.5.5 0 0 0-.5.5v6.5a.5.5 0 0 0 .5.5h6.5a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5ZM14.5 14a.5.5 0 0 0-.5.5V21a.5.5 0 0 0 .5.5H21a.5.5 0 0 0 .5-.5v-6.5a.5.5 0 0 0-.5-.5Z"></path> </svg> <div> <div class="color-fg-default h4">Actions</div> Automate any workflow </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;codespaces&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;codespaces_link_product_navbar&quot;}" href="https://github.com/features/codespaces"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-codespaces color-fg-subtle mr-3"> <path d="M3.5 3.75C3.5 2.784 4.284 2 5.25 2h13.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 18.75 13H5.25a1.75 1.75 0 0 1-1.75-1.75Zm-2 12c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v4a1.75 1.75 0 0 1-1.75 1.75H3.25a1.75 1.75 0 0 1-1.75-1.75ZM5.25 3.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h13.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Zm-2 12a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h17.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25Z"></path><path d="M10 17.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> <div> <div class="color-fg-default h4">Codespaces</div> Instant dev environments </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;issues&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;issues_link_product_navbar&quot;}" href="https://github.com/features/issues"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-issue-opened color-fg-subtle mr-3"> <path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Zm9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 14Z"></path> </svg> <div> <div class="color-fg-default h4">Issues</div> Plan and track work </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;code_review&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;code_review_link_product_navbar&quot;}" href="https://github.com/features/code-review"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-review color-fg-subtle mr-3"> <path d="M10.3 6.74a.75.75 0 0 1-.04 1.06l-2.908 2.7 2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M1.5 4.25c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v12.5a1.75 1.75 0 0 1-1.75 1.75h-9.69l-3.573 3.573A1.458 1.458 0 0 1 5 21.043V18.5H3.25a1.75 1.75 0 0 1-1.75-1.75ZM3.25 4a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 .75.75v3.19l3.72-3.72a.749.749 0 0 1 .53-.22h10a.25.25 0 0 0 .25-.25V4.25a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Review</div> Manage code changes </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;discussions&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;discussions_link_product_navbar&quot;}" href="https://github.com/features/discussions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Discussions</div> Collaborate outside of code </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;code_search&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;code_search_link_product_navbar&quot;}" href="https://github.com/features/code-search"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-square color-fg-subtle mr-3"> <path d="M10.3 8.24a.75.75 0 0 1-.04 1.06L7.352 12l2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M2 3.75C2 2.784 2.784 2 3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25Zm1.75-.25a.25.25 0 0 0-.25.25v16.5c0 .138.112.25.25.25h16.5a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Search</div> Find more, search less </div> </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="product-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="product-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;all_features&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;all_features_link_product_navbar&quot;}" href="https://github.com/features"> All features </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;documentation&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;documentation_link_product_navbar&quot;}" href="https://docs.github.com"> Documentation <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_skills&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_skills_link_product_navbar&quot;}" href="https://skills.github.com"> GitHub Skills <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;blog&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;blog_link_product_navbar&quot;}" href="https://github.blog"> Blog <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Solutions <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 pb-lg-3 mb-3 mb-lg-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-company-size-heading">By company size</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-company-size-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;enterprises&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}" href="https://github.com/enterprise"> Enterprises </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}" href="https://github.com/team"> Small and medium teams </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;startups&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}" href="https://github.com/enterprise/startups"> Startups </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;nonprofits&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}" href="/solutions/industry/nonprofits"> Nonprofits </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-use-case-heading">By use case</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-use-case-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devsecops&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}" href="/solutions/use-case/devsecops"> DevSecOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devops&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}" href="/solutions/use-case/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;ci_cd&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ci_cd_link_solutions_navbar&quot;}" href="/solutions/use-case/ci-cd"> CI/CD </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}" href="/solutions/use-case"> View all use cases </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-industry-heading">By industry</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-industry-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;healthcare&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}" href="/solutions/industry/healthcare"> Healthcare </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;financial_services&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}" href="/solutions/industry/financial-services"> Financial services </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;manufacturing&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}" href="/solutions/industry/manufacturing"> Manufacturing </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;government&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}" href="/solutions/industry/government"> Government </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all_industries&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}" href="/solutions/industry"> View all industries </a></li> </ul> </div> </div> <div class="HeaderMenu-trailing-link rounded-bottom-2 flex-shrink-0 mt-lg-4 px-lg-4 py-4 py-lg-3 f5 text-semibold"> <a href="/solutions"> View all solutions <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-right HeaderMenu-trailing-link-icon"> <path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path> </svg> </a> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Resources <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-topics-heading">Topics</span> <ul class="list-style-none f5" aria-labelledby="resources-topics-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;ai&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}" href="/resources/articles/ai"> AI </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devops&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}" href="/resources/articles/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;security&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}" href="/resources/articles/security"> Security </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;software_development&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}" href="/resources/articles/software-development"> Software Development </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_link_resources_navbar&quot;}" href="/resources/articles"> View all </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="resources-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;learning_pathways&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;learning_pathways_link_resources_navbar&quot;}" href="https://resources.github.com/learn/pathways"> Learning Pathways <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;white_papers_ebooks_webinars&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;white_papers_ebooks_webinars_link_resources_navbar&quot;}" href="https://resources.github.com"> White papers, Ebooks, Webinars <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;customer_stories&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}" href="https://github.com/customer-stories"> Customer Stories </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;partners&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}" href="https://partner.github.com"> Partners <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;executive_insights&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;executive_insights_link_resources_navbar&quot;}" href="https://github.com/solutions/executive-insights"> Executive Insights </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Open Source <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_sponsors&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}" href="/sponsors"> <div> <div class="color-fg-default h4">GitHub Sponsors</div> Fund open source developers </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;the_readme_project&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;the_readme_project_link_open_source_navbar&quot;}" href="https://github.com/readme"> <div> <div class="color-fg-default h4">The ReadME Project</div> GitHub community articles </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="open-source-repositories-heading">Repositories</span> <ul class="list-style-none f5" aria-labelledby="open-source-repositories-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;topics&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}" href="https://github.com/topics"> Topics </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;trending&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}" href="https://github.com/trending"> Trending </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;collections&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}" href="https://github.com/collections"> Collections </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Enterprise <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}" href="/enterprise"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-stack color-fg-subtle mr-3"> <path d="M11.063 1.456a1.749 1.749 0 0 1 1.874 0l8.383 5.316a1.751 1.751 0 0 1 0 2.956l-8.383 5.316a1.749 1.749 0 0 1-1.874 0L2.68 9.728a1.751 1.751 0 0 1 0-2.956Zm1.071 1.267a.25.25 0 0 0-.268 0L3.483 8.039a.25.25 0 0 0 0 .422l8.383 5.316a.25.25 0 0 0 .268 0l8.383-5.316a.25.25 0 0 0 0-.422Z"></path><path d="M1.867 12.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path><path d="M1.867 16.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path> </svg> <div> <div class="color-fg-default h4">Enterprise platform</div> AI-powered developer platform </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="enterprise-available-add-ons-heading">Available add-ons</span> <ul class="list-style-none f5" aria-labelledby="enterprise-available-add-ons-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;advanced_security&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;advanced_security_link_enterprise_navbar&quot;}" href="https://github.com/enterprise/advanced-security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Advanced Security</div> Enterprise-grade security features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_copilot&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_copilot_link_enterprise_navbar&quot;}" href="/features/copilot#enterprise"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">GitHub Copilot</div> Enterprise-grade AI features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;premium_support&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}" href="/premium-support"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Premium Support</div> Enterprise-grade 24/7 support </div> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <a class="HeaderMenu-link no-underline px-0 px-lg-2 py-3 py-lg-2 d-block d-lg-inline-block" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;pricing&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;pricing_link_global_navbar&quot;}" href="https://github.com/pricing">Pricing</a> </li> </ul> </nav> <div class="d-flex flex-column flex-lg-row width-full flex-justify-end flex-lg-items-center text-center mt-3 mt-lg-0 text-lg-left ml-lg-3"> <qbsearch-input class="search-input" data-scope="repo:kubernetes/community" data-custom-scopes-path="/search/custom_scopes" data-delete-custom-scopes-csrf="628TOH9JVt15sm8F5aBUa1ZrXZOrRAAK9yxO_LORHSg11SMbnnatFHox-ECfmlxIor-LKpe56V5lUWoNH6oMMA" data-max-custom-scopes="10" data-header-redesign-enabled="false" data-initial-value="" data-blackbird-suggestions-path="/search/suggestions" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" data-current-repository="kubernetes/community" data-current-org="kubernetes" data-current-owner="" data-logged-in="false" data-copilot-chat-enabled="false" data-nl-search-enabled="false" data-retain-scroll-position="true"> <div class="search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center mr-4 rounded" data-action="click:qbsearch-input#searchInputContainerClicked" > <button type="button" class="header-search-button placeholder input-button form-control d-flex flex-1 flex-self-stretch flex-items-center no-wrap width-full py-0 pl-2 pr-0 text-left border-0 box-shadow-none" data-target="qbsearch-input.inputButton" aria-label="Search or jump to…" aria-haspopup="dialog" placeholder="Search or jump to..." data-hotkey=s,/ autocapitalize="off" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;searchbar&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}" data-action="click:qbsearch-input#handleExpand" > <div class="mr-2 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </div> <span class="flex-1" data-target="qbsearch-input.inputButtonText">Search or jump to...</span> <div class="d-flex" data-target="qbsearch-input.hotkeyIndicator"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg> </div> </button> <input type="hidden" name="type" class="js-site-search-type-field"> <div class="Overlay--hidden " data-modal-dialog-overlay> <modal-dialog data-action="close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose" data-target="qbsearch-input.searchSuggestionsDialog" role="dialog" id="search-suggestions-dialog" aria-modal="true" aria-labelledby="search-suggestions-dialog-header" data-view-component="true" class="Overlay Overlay--width-large Overlay--height-auto"> <h1 id="search-suggestions-dialog-header" class="sr-only">Search code, repositories, users, issues, pull requests...</h1> <div class="Overlay-body Overlay-body--paddingNone"> <div data-view-component="true"> <div class="search-suggestions position-fixed width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container" style="border-radius: 12px;" data-target="qbsearch-input.queryBuilderContainer" hidden > <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="query-builder-test-form" action="" accept-charset="UTF-8" method="get"> <query-builder data-target="qbsearch-input.queryBuilder" id="query-builder-query-builder-test" data-filter-key=":" data-view-component="true" class="QueryBuilder search-query-builder"> <div class="FormControl FormControl--fullWidth"> <label id="query-builder-test-label" for="query-builder-test" class="FormControl-label sr-only"> Search </label> <div class="QueryBuilder-StyledInput width-fit " data-target="query-builder.styledInput" > <span id="query-builder-test-leadingvisual-wrap" class="FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search FormControl-input-leadingVisual"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </span> <div data-target="query-builder.styledInputContainer" class="QueryBuilder-StyledInputContainer"> <div aria-hidden="true" class="QueryBuilder-StyledInputContent" data-target="query-builder.styledInputContent" ></div> <div class="QueryBuilder-InputWrapper"> <div aria-hidden="true" class="QueryBuilder-Sizer" data-target="query-builder.sizer"></div> <input id="query-builder-test" name="query-builder-test" value="" autocomplete="off" type="text" role="combobox" spellcheck="false" aria-expanded="false" aria-describedby="validation-7f810606-0920-4be9-8c67-5a50d3a22382" data-target="query-builder.input" data-action=" input:query-builder#inputChange blur:query-builder#inputBlur keydown:query-builder#inputKeydown focus:query-builder#inputFocus " data-view-component="true" class="FormControl-input QueryBuilder-Input FormControl-medium" /> </div> </div> <span class="sr-only" id="query-builder-test-clear">Clear</span> <button role="button" id="query-builder-test-clear-button" aria-labelledby="query-builder-test-clear query-builder-test-label" data-target="query-builder.clearButton" data-action=" click:query-builder#clear focus:query-builder#clearButtonFocus blur:query-builder#clearButtonBlur " variant="small" hidden="hidden" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium mr-1 px-2 py-0 d-flex flex-items-center rounded-1 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill Button-visual"> <path d="M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z"></path> </svg> </button> </div> <template id="search-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </template> <template id="code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="file-code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file-code"> <path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path> </svg> </template> <template id="history-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-history"> <path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path> </svg> </template> <template id="repo-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> </template> <template id="bookmark-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bookmark"> <path d="M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="plus-circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus-circle"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill"> <path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path> </svg> </template> <template id="trash-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-trash"> <path d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path> </svg> </template> <template id="team-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people"> <path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path> </svg> </template> <template id="project-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project"> <path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z"></path> </svg> </template> <template id="pencil-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pencil"> <path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"></path> </svg> </template> <template id="copilot-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot"> <path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="copilot-error-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot-error"> <path d="M16 11.24c0 .112-.072.274-.21.467L13 9.688V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-.198 0-.388-.009-.571-.029L6.833 5.226a4.01 4.01 0 0 0 .17-.782c.117-.935-.037-1.395-.241-1.614-.193-.206-.637-.413-1.682-.297-.683.076-1.115.231-1.395.415l-1.257-.91c.579-.564 1.413-.877 2.485-.996 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095Zm-5.083-8.707c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Zm2.511 11.074c-1.393.776-3.272 1.428-5.43 1.428-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.18-.455-.241-.963-.252-1.475L.31 4.107A.747.747 0 0 1 0 3.509V3.49a.748.748 0 0 1 .625-.73c.156-.026.306.047.435.139l14.667 10.578a.592.592 0 0 1 .227.264.752.752 0 0 1 .046.249v.022a.75.75 0 0 1-1.19.596Zm-1.367-.991L5.635 7.964a5.128 5.128 0 0 1-.889.073c-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433 1.539 0 3.089-.505 4.063-.934Z"></path> </svg> </template> <template id="workflow-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-workflow"> <path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="book-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book"> <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path> </svg> </template> <template id="code-review-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-review"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="codespaces-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-codespaces"> <path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> </template> <template id="comment-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment"> <path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="comment-discussion-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion"> <path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path> </svg> </template> <template id="organization-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization"> <path d="M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="rocket-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-rocket"> <path d="M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </template> <template id="shield-check-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield-check"> <path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="heart-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-heart"> <path d="m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z"></path> </svg> </template> <template id="server-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="globe-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path> </svg> </template> <template id="issue-opened-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </template> <template id="device-mobile-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-mobile"> <path d="M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path> </svg> </template> <template id="package-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package"> <path d="m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z"></path> </svg> </template> <template id="credit-card-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-credit-card"> <path d="M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z"></path><path d="M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z"></path> </svg> </template> <template id="play-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </template> <template id="gift-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-gift"> <path d="M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z"></path> </svg> </template> <template id="code-square-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-square"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="device-desktop-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-desktop"> <path d="M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z"></path> </svg> </template> <div class="position-relative"> <ul role="listbox" class="ActionListWrap QueryBuilder-ListWrap" aria-label="Suggestions" data-action=" combobox-commit:query-builder#comboboxCommit mousedown:query-builder#resultsMousedown " data-target="query-builder.resultsList" data-persist-list=false id="query-builder-test-results" ></ul> </div> <div class="FormControl-inlineValidation" id="validation-7f810606-0920-4be9-8c67-5a50d3a22382" hidden="hidden"> <span class="FormControl-inlineValidation--visual"> <svg aria-hidden="true" height="12" viewBox="0 0 12 12" version="1.1" width="12" data-view-component="true" class="octicon octicon-alert-fill"> <path d="M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"></path> </svg> </span> <span></span> </div> </div> <div data-target="query-builder.screenReaderFeedback" aria-live="polite" aria-atomic="true" class="sr-only"></div> </query-builder></form> <div class="d-flex flex-row color-fg-muted px-3 text-small color-bg-default search-feedback-prompt"> <a target="_blank" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax" data-view-component="true" class="Link color-fg-accent text-normal ml-2">Search syntax tips</a> <div class="d-flex flex-1"></div> </div> </div> </div> </div> </modal-dialog></div> </div> <div data-action="click:qbsearch-input#retract" class="dark-backdrop position-fixed" hidden data-target="qbsearch-input.darkBackdrop"></div> <div class="color-fg-default"> <dialog-helper> <dialog data-target="qbsearch-input.feedbackDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="feedback-dialog" aria-modal="true" aria-labelledby="feedback-dialog-title" aria-describedby="feedback-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="feedback-dialog-title"> Provide feedback </h1> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="feedback-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="feedback-dialog-title"> <div data-view-component="true" class="Overlay-body"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="code-search-feedback-form" data-turbo="false" action="/search/feedback" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="NDDOYM7DBagfqo308rZytk4Dg0OTjTdhEGE6pWWVaarEueNcKya0xvMDstvOtSI+swdqRBput2l9ypnn8nRJUw==" /> <p>We read every piece of feedback, and take your input very seriously.</p> <textarea name="feedback" class="form-control width-full mb-2" style="height: 120px" id="feedback"></textarea> <input name="include_email" id="include_email" aria-label="Include my email address so I can be contacted" class="form-control mr-2" type="checkbox"> <label for="include_email" style="font-weight: normal">Include my email address so I can be contacted</label> </form></div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd"> <button data-close-dialog-id="feedback-dialog" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="code-search-feedback-form" data-action="click:qbsearch-input#submitFeedback" type="submit" data-view-component="true" class="btn-primary btn"> Submit feedback </button> </div> </dialog></dialog-helper> <custom-scopes data-target="qbsearch-input.customScopesManager"> <dialog-helper> <dialog data-target="custom-scopes.customScopesModalDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="custom-scopes-dialog" aria-modal="true" aria-labelledby="custom-scopes-dialog-title" aria-describedby="custom-scopes-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header Overlay-header--divided"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="custom-scopes-dialog-title"> Saved searches </h1> <h2 id="custom-scopes-dialog-description" class="Overlay-description">Use saved searches to filter your results more quickly</h2> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="custom-scopes-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="custom-scopes-dialog-title"> <div data-view-component="true" class="Overlay-body"> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <div hidden class="create-custom-scope-form" data-target="custom-scopes.createCustomScopeForm"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="custom-scopes-dialog-form" data-turbo="false" action="/search/custom_scopes" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="Kjdx6OffP9UswqetHcJ6SCJh/mLc06yoV1B7G/V6DvgUHzryy2JNLF8zgLdpVY635bxTKC0dC3DZvo6RkxhOFg==" /> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <input type="hidden" id="custom_scope_id" name="custom_scope_id" data-target="custom-scopes.customScopesIdField"> <div class="form-group"> <label for="custom_scope_name">Name</label> <auto-check src="/search/custom_scopes/check_name" required only-validate-on-blur="false"> <input type="text" name="custom_scope_name" id="custom_scope_name" data-target="custom-scopes.customScopesNameField" class="form-control" autocomplete="off" placeholder="github-ruby" required maxlength="50"> <input type="hidden" data-csrf="true" value="acUUAlVfvroDr1b69x2M1C93uus+K4riJKVfrHYuGedlGs8Mt68Jr83+h3Xq772RmvZYNuUNHibN4eIjiUKYqg==" /> </auto-check> </div> <div class="form-group"> <label for="custom_scope_query">Query</label> <input type="text" name="custom_scope_query" id="custom_scope_query" data-target="custom-scopes.customScopesQueryField" class="form-control" autocomplete="off" placeholder="(repo:mona/a OR repo:mona/b) AND lang:python" required maxlength="500"> </div> <p class="text-small color-fg-muted"> To see all available qualifiers, see our <a class="Link--inTextBlock" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax">documentation</a>. </p> </form> </div> <div data-target="custom-scopes.manageCustomScopesForm"> <div data-target="custom-scopes.list"></div> </div> </div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided"> <button data-action="click:custom-scopes#customScopesCancel" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="custom-scopes-dialog-form" data-action="click:custom-scopes#customScopesSubmit" data-target="custom-scopes.customScopesSubmitButton" type="submit" data-view-component="true" class="btn-primary btn"> Create saved search </button> </div> </dialog></dialog-helper> </custom-scopes> </div> </qbsearch-input> <div class="position-relative HeaderMenu-link-wrap d-lg-inline-block"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fkubernetes%2Fcommunity%2Fblob%2Fmaster%2Fcontributors%2Fdevel%2Fsig-architecture%2Fapi-conventions.md" class="HeaderMenu-link HeaderMenu-link--sign-in HeaderMenu-button flex-shrink-0 no-underline d-none d-lg-inline-flex border border-lg-0 rounded rounded-lg-0 px-2 py-1" style="margin-left: 12px;" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="86e9f362b1517270a3192b0a7ace0593167890241543f2eea734ecca93d771a4" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}" > Sign in </a> </div> <a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=kubernetes%2Fcommunity" class="HeaderMenu-link HeaderMenu-link--sign-up HeaderMenu-button flex-shrink-0 d-flex d-lg-inline-flex no-underline border color-border-default rounded px-2 py-1" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="86e9f362b1517270a3192b0a7ace0593167890241543f2eea734ecca93d771a4" data-analytics-event="{&quot;category&quot;:&quot;Sign up&quot;,&quot;action&quot;:&quot;click to sign up for account&quot;,&quot;label&quot;:&quot;ref_page:/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show;ref_cta:Sign up;ref_loc:header logged out&quot;}" > Sign up </a> <button type="button" class="sr-only js-header-menu-focus-trap d-block d-lg-none">Reseting focus</button> </div> </div> </div> </div> </header> <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <button id="icon-button-b6389d92-3107-49c4-8bfa-687e85023a0c" aria-labelledby="tooltip-74e01e3d-c75b-4337-9360-e526ced8d853" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button><tool-tip id="tooltip-74e01e3d-c75b-4337-9360-e526ced8d853" for="icon-button-b6389d92-3107-49c4-8bfa-687e85023a0c" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip> </div> </div> <div id="start-of-content" class="show-on-focus"></div> <div id="js-flash-container" class="flash-container" data-turbo-replace> <template class="js-flash-template"> <div class="flash flash-full {{ className }}"> <div > <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div aria-atomic="true" role="alert" class="js-flash-alert"> <div>{{ message }}</div> </div> </div> </div> </template> </div> <div class="application-main " data-commit-hovercards-enabled data-discussion-hovercards-enabled data-issue-and-pr-hovercards-enabled data-project-hovercards-enabled > <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class=""> <main id="js-repo-pjax-container" > <div id="repository-container-header" class="pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace> <div class="d-flex flex-nowrap flex-justify-end mb-3 px-3 px-lg-5" style="gap: 1rem;"> <div class="flex-auto min-width-0 width-fit"> <div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> <span class="author flex-self-stretch" itemprop="author"> <a class="url fn" rel="author" data-hovercard-type="organization" data-hovercard-url="/orgs/kubernetes/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/kubernetes"> kubernetes </a> </span> <span class="mx-1 flex-self-stretch color-fg-muted">/</span> <strong itemprop="name" class="mr-2 flex-self-stretch"> <a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/kubernetes/community">community</a> </strong> <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span> </div> </div> <div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;"> <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;"> <li> <a href="/login?return_to=%2Fkubernetes%2Fcommunity" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="11ca0f8a1a7824bed23948e8050014b364fcc453f13fe8ed4ebc27367b0fb83d" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2"> <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path> </svg>Notifications </a> <tool-tip id="tooltip-69369218-ebed-4b48-a045-749ab4e766f9" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip> </li> <li> <a icon="repo-forked" id="fork-button" href="/login?return_to=%2Fkubernetes%2Fcommunity" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:57939112,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="3af23831d5b0c7e6b65cabd9dcc168bb3ee1987de9582e6869e864fb7dbd53bf" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2"> <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path> </svg>Fork <span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="5,202" data-view-component="true" class="Counter">5.2k</span> </a> </li> <li> <div data-view-component="true" class="BtnGroup d-flex"> <a href="/login?return_to=%2Fkubernetes%2Fcommunity" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:57939112,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="fa905869b5814dcf207430729b705278fe7095a2fa4def6615cd8097aa5ee89c" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg><span data-view-component="true" class="d-inline"> Star </span> <span id="repo-stars-counter-star" aria-label="12152 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="12,152" data-view-component="true" class="Counter js-social-count">12.2k</span> </a></div> </li> </ul> </div> </div> <div id="responsive-meta-container" data-turbo-replace> </div> <nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 px-md-4 px-lg-5"> <ul data-view-component="true" class="UnderlineNav-body list-style-none"> <li data-view-component="true" class="d-inline-flex"> <a id="code-tab" href="/kubernetes/community" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /kubernetes/community" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> <span data-content="Code">Code</span> <span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="issues-tab" href="/kubernetes/community/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /kubernetes/community/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> <span data-content="Issues">Issues</span> <span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="116" data-view-component="true" class="Counter">116</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="pull-requests-tab" href="/kubernetes/community/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /kubernetes/community/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> <span data-content="Pull requests">Pull requests</span> <span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="52" data-view-component="true" class="Counter">52</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="actions-tab" href="/kubernetes/community/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /kubernetes/community/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> <span data-content="Actions">Actions</span> <span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="projects-tab" href="/kubernetes/community/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /kubernetes/community/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> <span data-content="Projects">Projects</span> <span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="security-tab" href="/kubernetes/community/security" data-tab-item="i5security-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /kubernetes/community/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span data-content="Security">Security</span> <include-fragment src="/kubernetes/community/security/overall-count" accept="text/fragment+html"></include-fragment> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="insights-tab" href="/kubernetes/community/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /kubernetes/community/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> <span data-content="Insights">Insights</span> <span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> </ul> <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 pr-md-4 pr-lg-5 right-0"> <action-menu data-select-variant="none" data-view-component="true"> <focus-group direction="vertical" mnemonics retain> <button id="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-button" popovertarget="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-overlay" aria-controls="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-list" aria-haspopup="true" aria-labelledby="tooltip-781e6441-d9cb-425a-97f2-9f1f737b556e" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual"> <path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path> </svg> </button><tool-tip id="tooltip-781e6441-d9cb-425a-97f2-9f1f737b556e" for="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip> <anchored-position data-target="action-menu.overlay" id="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-overlay" anchor="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true"> <div data-view-component="true" class="Overlay Overlay--size-auto"> <div data-view-component="true" class="Overlay-body Overlay-body--paddingNone"> <action-list> <div data-view-component="true"> <ul aria-labelledby="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-button" id="action-menu-727dbc6a-e212-4010-b948-dc7eb21e1088-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap"> <li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-85b7cf24-8f0f-481c-ba99-c1f468e09ea2" href="/kubernetes/community" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Code </span> </a> </li> <li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-b86148f1-0479-4dd9-aaf0-f33131b10c98" href="/kubernetes/community/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Issues </span> </a> </li> <li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-dab336b0-405b-4aad-b2fd-d6bed080b541" href="/kubernetes/community/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Pull requests </span> </a> </li> <li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-d3e87b58-46ac-43a7-85d8-b7a62bb198c5" href="/kubernetes/community/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Actions </span> </a> </li> <li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-1489089b-9e1b-4af7-b65c-be64a0f305b3" href="/kubernetes/community/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Projects </span> </a> </li> <li hidden="hidden" data-menu-item="i5security-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-b7ffabc6-0e53-47d0-a062-9cc273b05f44" href="/kubernetes/community/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Security </span> </a> </li> <li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-3debb992-6f95-4054-899d-b43a54d61855" href="/kubernetes/community/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Insights </span> </a> </li> </ul> </div></action-list> </div> </div></anchored-position> </focus-group> </action-menu></div> </nav> </div> <turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class=""> <div id="repo-content-pjax-container" class="repository-content " > <react-app app-name="react-code-view" initial-path="/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md" style="display: block; min-height: calc(100vh - 64px);" data-attempted-ssr="true" data-ssr="true" data-lazy="false" data-alternate="false" data-data-router-enabled="false" > <script type="application/json" data-target="react-app.embeddedData">{"payload":{"allShortcutsEnabled":false,"fileTree":{"contributors/devel/sig-architecture":{"items":[{"name":"OWNERS","path":"contributors/devel/sig-architecture/OWNERS","contentType":"file"},{"name":"api-conventions.md","path":"contributors/devel/sig-architecture/api-conventions.md","contentType":"file"},{"name":"api_changes.md","path":"contributors/devel/sig-architecture/api_changes.md","contentType":"file"},{"name":"component-config-conventions.md","path":"contributors/devel/sig-architecture/component-config-conventions.md","contentType":"file"},{"name":"conformance-tests.md","path":"contributors/devel/sig-architecture/conformance-tests.md","contentType":"file"},{"name":"feature-gates.md","path":"contributors/devel/sig-architecture/feature-gates.md","contentType":"file"},{"name":"godep.md","path":"contributors/devel/sig-architecture/godep.md","contentType":"file"},{"name":"object-lifecycle.md","path":"contributors/devel/sig-architecture/object-lifecycle.md","contentType":"file"},{"name":"staging.md","path":"contributors/devel/sig-architecture/staging.md","contentType":"file"},{"name":"vendor.md","path":"contributors/devel/sig-architecture/vendor.md","contentType":"file"}],"totalCount":10},"contributors/devel":{"items":[{"name":"sig-api-machinery","path":"contributors/devel/sig-api-machinery","contentType":"directory"},{"name":"sig-architecture","path":"contributors/devel/sig-architecture","contentType":"directory"},{"name":"sig-cli","path":"contributors/devel/sig-cli","contentType":"directory"},{"name":"sig-instrumentation","path":"contributors/devel/sig-instrumentation","contentType":"directory"},{"name":"sig-node","path":"contributors/devel/sig-node","contentType":"directory"},{"name":"sig-release","path":"contributors/devel/sig-release","contentType":"directory"},{"name":"sig-scalability","path":"contributors/devel/sig-scalability","contentType":"directory"},{"name":"sig-scheduling","path":"contributors/devel/sig-scheduling","contentType":"directory"},{"name":"sig-storage","path":"contributors/devel/sig-storage","contentType":"directory"},{"name":"sig-testing","path":"contributors/devel/sig-testing","contentType":"directory"},{"name":"OWNERS","path":"contributors/devel/OWNERS","contentType":"file"},{"name":"README.md","path":"contributors/devel/README.md","contentType":"file"},{"name":"automation.md","path":"contributors/devel/automation.md","contentType":"file"},{"name":"development.md","path":"contributors/devel/development.md","contentType":"file"},{"name":"running-locally.md","path":"contributors/devel/running-locally.md","contentType":"file"}],"totalCount":15},"contributors":{"items":[{"name":"chairs-and-techleads","path":"contributors/chairs-and-techleads","contentType":"directory"},{"name":"design-proposals","path":"contributors/design-proposals","contentType":"directory"},{"name":"devel","path":"contributors/devel","contentType":"directory"},{"name":"guide","path":"contributors/guide","contentType":"directory"},{"name":"OWNERS","path":"contributors/OWNERS","contentType":"file"}],"totalCount":5},"":{"items":[{"name":".github","path":".github","contentType":"directory"},{"name":"archive","path":"archive","contentType":"directory"},{"name":"committee-code-of-conduct","path":"committee-code-of-conduct","contentType":"directory"},{"name":"committee-security-response","path":"committee-security-response","contentType":"directory"},{"name":"committee-steering","path":"committee-steering","contentType":"directory"},{"name":"communication","path":"communication","contentType":"directory"},{"name":"contributors","path":"contributors","contentType":"directory"},{"name":"elections","path":"elections","contentType":"directory"},{"name":"events","path":"events","contentType":"directory"},{"name":"generator","path":"generator","contentType":"directory"},{"name":"github-management","path":"github-management","contentType":"directory"},{"name":"hack","path":"hack","contentType":"directory"},{"name":"icons","path":"icons","contentType":"directory"},{"name":"mentoring","path":"mentoring","contentType":"directory"},{"name":"sig-api-machinery","path":"sig-api-machinery","contentType":"directory"},{"name":"sig-apps","path":"sig-apps","contentType":"directory"},{"name":"sig-architecture","path":"sig-architecture","contentType":"directory"},{"name":"sig-auth","path":"sig-auth","contentType":"directory"},{"name":"sig-autoscaling","path":"sig-autoscaling","contentType":"directory"},{"name":"sig-cli","path":"sig-cli","contentType":"directory"},{"name":"sig-cloud-provider","path":"sig-cloud-provider","contentType":"directory"},{"name":"sig-cluster-lifecycle","path":"sig-cluster-lifecycle","contentType":"directory"},{"name":"sig-contributor-experience","path":"sig-contributor-experience","contentType":"directory"},{"name":"sig-docs","path":"sig-docs","contentType":"directory"},{"name":"sig-etcd","path":"sig-etcd","contentType":"directory"},{"name":"sig-instrumentation","path":"sig-instrumentation","contentType":"directory"},{"name":"sig-k8s-infra","path":"sig-k8s-infra","contentType":"directory"},{"name":"sig-multicluster","path":"sig-multicluster","contentType":"directory"},{"name":"sig-network","path":"sig-network","contentType":"directory"},{"name":"sig-node","path":"sig-node","contentType":"directory"},{"name":"sig-release","path":"sig-release","contentType":"directory"},{"name":"sig-scalability","path":"sig-scalability","contentType":"directory"},{"name":"sig-scheduling","path":"sig-scheduling","contentType":"directory"},{"name":"sig-security","path":"sig-security","contentType":"directory"},{"name":"sig-storage","path":"sig-storage","contentType":"directory"},{"name":"sig-testing","path":"sig-testing","contentType":"directory"},{"name":"sig-ui","path":"sig-ui","contentType":"directory"},{"name":"sig-windows","path":"sig-windows","contentType":"directory"},{"name":"wg-batch","path":"wg-batch","contentType":"directory"},{"name":"wg-data-protection","path":"wg-data-protection","contentType":"directory"},{"name":"wg-device-management","path":"wg-device-management","contentType":"directory"},{"name":"wg-etcd-operator","path":"wg-etcd-operator","contentType":"directory"},{"name":"wg-lts","path":"wg-lts","contentType":"directory"},{"name":"wg-policy","path":"wg-policy","contentType":"directory"},{"name":"wg-serving","path":"wg-serving","contentType":"directory"},{"name":"wg-structured-logging","path":"wg-structured-logging","contentType":"directory"},{"name":".generated_files","path":".generated_files","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"CLA.md","path":"CLA.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"Makefile","path":"Makefile","contentType":"file"},{"name":"OWNERS","path":"OWNERS","contentType":"file"},{"name":"OWNERS_ALIASES","path":"OWNERS_ALIASES","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"SECURITY.md","path":"SECURITY.md","contentType":"file"},{"name":"SECURITY_CONTACTS","path":"SECURITY_CONTACTS","contentType":"file"},{"name":"SIG-diagram.png","path":"SIG-diagram.png","contentType":"file"},{"name":"SIG-diagram.svg","path":"SIG-diagram.svg","contentType":"file"},{"name":"code-of-conduct.md","path":"code-of-conduct.md","contentType":"file"},{"name":"community-membership.md","path":"community-membership.md","contentType":"file"},{"name":"go.mod","path":"go.mod","contentType":"file"},{"name":"go.sum","path":"go.sum","contentType":"file"},{"name":"governance.md","path":"governance.md","contentType":"file"},{"name":"kubernetes_governance_diagram.png","path":"kubernetes_governance_diagram.png","contentType":"file"},{"name":"liaisons.md","path":"liaisons.md","contentType":"file"},{"name":"sig-list.md","path":"sig-list.md","contentType":"file"},{"name":"sig-wg-lifecycle.md","path":"sig-wg-lifecycle.md","contentType":"file"},{"name":"sigs.yaml","path":"sigs.yaml","contentType":"file"},{"name":"values.md","path":"values.md","contentType":"file"}],"totalCount":70}},"fileTreeProcessingTime":27.318253000000002,"foldersToFetch":[],"repo":{"id":57939112,"defaultBranch":"master","name":"community","ownerLogin":"kubernetes","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2016-05-03T03:36:05.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/13629408?v=4","public":true,"private":false,"isOrgOwned":true},"codeLineWrapEnabled":false,"symbolsExpanded":false,"treeExpanded":true,"refInfo":{"name":"master","listCacheKey":"v0:1657654207.596281","canEdit":false,"refType":"branch","currentOid":"13e8c6eaa52ca1ee9d5c308ecc3c98f90aca6d0c"},"path":"contributors/devel/sig-architecture/api-conventions.md","currentUser":null,"blob":{"rawLines":null,"stylingDirectives":null,"colorizedLines":null,"csv":null,"csvError":null,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/kubernetes/community/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"api-conventions.md","displayUrl":"https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md?raw=true","headerInfo":{"blobSize":"105 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"cf49d9a","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fkubernetes%2Fcommunity%2Fblob%2Fmaster%2Fcontributors%2Fdevel%2Fsig-architecture%2Fapi-conventions.md","isCSV":false,"isRichtext":true,"toc":[{"level":1,"text":"API Conventions","anchor":"api-conventions","htmlText":"API Conventions"},{"level":2,"text":"Types (Kinds)","anchor":"types-kinds","htmlText":"Types (Kinds)"},{"level":3,"text":"Resources","anchor":"resources","htmlText":"Resources"},{"level":3,"text":"Objects","anchor":"objects","htmlText":"Objects"},{"level":4,"text":"Metadata","anchor":"metadata","htmlText":"Metadata"},{"level":4,"text":"Spec and Status","anchor":"spec-and-status","htmlText":"Spec and Status"},{"level":5,"text":"Typical status properties","anchor":"typical-status-properties","htmlText":"Typical status properties"},{"level":4,"text":"References to related objects","anchor":"references-to-related-objects","htmlText":"References to related objects"},{"level":4,"text":"Lists of named subobjects preferred over maps","anchor":"lists-of-named-subobjects-preferred-over-maps","htmlText":"Lists of named subobjects preferred over maps"},{"level":4,"text":"Primitive types","anchor":"primitive-types","htmlText":"Primitive types"},{"level":4,"text":"Constants","anchor":"constants","htmlText":"Constants"},{"level":4,"text":"Unions","anchor":"unions","htmlText":"Unions"},{"level":3,"text":"Lists and Simple kinds","anchor":"lists-and-simple-kinds","htmlText":"Lists and Simple kinds"},{"level":2,"text":"Differing Representations","anchor":"differing-representations","htmlText":"Differing Representations"},{"level":2,"text":"Verbs on Resources","anchor":"verbs-on-resources","htmlText":"Verbs on Resources"},{"level":3,"text":"PATCH operations","anchor":"patch-operations","htmlText":"PATCH operations"},{"level":2,"text":"Short-names and Categories","anchor":"short-names-and-categories","htmlText":"Short-names and Categories"},{"level":3,"text":"Short-names","anchor":"short-names","htmlText":"Short-names"},{"level":3,"text":"Categories","anchor":"categories","htmlText":"Categories"},{"level":2,"text":"Idempotency","anchor":"idempotency","htmlText":"Idempotency"},{"level":2,"text":"Optional vs. Required","anchor":"optional-vs-required","htmlText":"Optional vs. Required"},{"level":2,"text":"Defaulting","anchor":"defaulting","htmlText":"Defaulting"},{"level":3,"text":"Static Defaults","anchor":"static-defaults","htmlText":"Static Defaults"},{"level":3,"text":"Admission Controlled Defaults","anchor":"admission-controlled-defaults","htmlText":"Admission Controlled Defaults"},{"level":3,"text":"Controller-Assigned Defaults (aka Late Initialization)","anchor":"controller-assigned-defaults-aka-late-initialization","htmlText":"Controller-Assigned Defaults (aka Late Initialization)"},{"level":3,"text":"What May Be Defaulted","anchor":"what-may-be-defaulted","htmlText":"What May Be Defaulted"},{"level":3,"text":"Considerations For PUT Operations","anchor":"considerations-for-put-operations","htmlText":"Considerations For PUT Operations"},{"level":2,"text":"Concurrency Control and Consistency","anchor":"concurrency-control-and-consistency","htmlText":"Concurrency Control and Consistency"},{"level":2,"text":"Serialization Format","anchor":"serialization-format","htmlText":"Serialization Format"},{"level":2,"text":"Units","anchor":"units","htmlText":"Units"},{"level":2,"text":"Selecting Fields","anchor":"selecting-fields","htmlText":"Selecting Fields"},{"level":2,"text":"Object references","anchor":"object-references","htmlText":"Object references"},{"level":3,"text":"Naming of the reference field","anchor":"naming-of-the-reference-field","htmlText":"Naming of the reference field"},{"level":3,"text":"Referencing resources with multiple versions","anchor":"referencing-resources-with-multiple-versions","htmlText":"Referencing resources with multiple versions"},{"level":3,"text":"Handling of resources that do not exist","anchor":"handling-of-resources-that-do-not-exist","htmlText":"Handling of resources that do not exist"},{"level":3,"text":"Validation of fields","anchor":"validation-of-fields","htmlText":"Validation of fields"},{"level":3,"text":"Do not modify the referred object","anchor":"do-not-modify-the-referred-object","htmlText":"Do not modify the referred object"},{"level":3,"text":"Minimize copying or printing values to the referrer object","anchor":"minimize-copying-or-printing-values-to-the-referrer-object","htmlText":"Minimize copying or printing values to the referrer object"},{"level":3,"text":"Object References Examples","anchor":"object-references-examples","htmlText":"Object References Examples"},{"level":4,"text":"Single resource reference","anchor":"single-resource-reference","htmlText":"Single resource reference"},{"level":5,"text":"Controller behavior","anchor":"controller-behavior","htmlText":"Controller behavior"},{"level":4,"text":"Multiple resource reference","anchor":"multiple-resource-reference","htmlText":"Multiple resource reference"},{"level":5,"text":"Kind vs. Resource","anchor":"kind-vs-resource","htmlText":"Kind vs. Resource"},{"level":5,"text":"Controller behavior","anchor":"controller-behavior-1","htmlText":"Controller behavior"},{"level":4,"text":"Generic object reference","anchor":"generic-object-reference","htmlText":"Generic object reference"},{"level":5,"text":"Controller behavior","anchor":"controller-behavior-2","htmlText":"Controller behavior"},{"level":4,"text":"Field reference","anchor":"field-reference","htmlText":"Field reference"},{"level":5,"text":"Controller behavior","anchor":"controller-behavior-3","htmlText":"Controller behavior"},{"level":2,"text":"HTTP Status codes","anchor":"http-status-codes","htmlText":"HTTP Status codes"},{"level":4,"text":"Success codes","anchor":"success-codes","htmlText":"Success codes"},{"level":4,"text":"Error codes","anchor":"error-codes","htmlText":"Error codes"},{"level":2,"text":"Response Status Kind","anchor":"response-status-kind","htmlText":"Response Status Kind"},{"level":2,"text":"Events","anchor":"events","htmlText":"Events"},{"level":2,"text":"Naming conventions","anchor":"naming-conventions","htmlText":"Naming conventions"},{"level":3,"text":"Namespace Names","anchor":"namespace-names","htmlText":"Namespace Names"},{"level":2,"text":"Label, selector, and annotation conventions","anchor":"label-selector-and-annotation-conventions","htmlText":"Label, selector, and annotation conventions"},{"level":2,"text":"WebSockets and SPDY","anchor":"websockets-and-spdy","htmlText":"WebSockets and SPDY"},{"level":2,"text":"Validation","anchor":"validation","htmlText":"Validation"},{"level":2,"text":"Automatic Resource Allocation And Deallocation","anchor":"automatic-resource-allocation-and-deallocation","htmlText":"Automatic Resource Allocation And Deallocation"},{"level":2,"text":"Representing Allocated Values","anchor":"representing-allocated-values","htmlText":"Representing Allocated Values"},{"level":3,"text":"When to use a spec field","anchor":"when-to-use-a-spec-field","htmlText":"When to use a spec field"},{"level":3,"text":"When to use a status field","anchor":"when-to-use-a-status-field","htmlText":"When to use a status field"},{"level":4,"text":"Sequencing operations","anchor":"sequencing-operations","htmlText":"Sequencing operations"},{"level":3,"text":"When to use a different type","anchor":"when-to-use-a-different-type","htmlText":"When to use a different type"}],"lineInfo":{"truncatedLoc":"2080","truncatedSloc":"1682"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"issueTemplate":null,"discussionTemplate":null,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/kubernetes/community/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/kubernetes/community/raw/refs/heads/master/contributors/devel/sig-architecture/api-conventions.md","renderImageOrRaw":false,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAPI Conventions\u003c/h1\u003e\u003ca id=\"user-content-api-conventions\" class=\"anchor\" aria-label=\"Permalink: API Conventions\" href=\"#api-conventions\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eThis document is oriented at users who want a deeper understanding of the\nKubernetes API structure, and developers wanting to extend the Kubernetes API.\nAn introduction to using resources with kubectl can be found in \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/\" rel=\"nofollow\"\u003ethe object management overview\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eTable of Contents\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#types-kinds\"\u003eTypes (Kinds)\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#resources\"\u003eResources\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#objects\"\u003eObjects\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#metadata\"\u003eMetadata\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#spec-and-status\"\u003eSpec and Status\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#typical-status-properties\"\u003eTypical status properties\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#references-to-related-objects\"\u003eReferences to related objects\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#lists-of-named-subobjects-preferred-over-maps\"\u003eLists of named subobjects preferred over maps\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#primitive-types\"\u003ePrimitive types\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#constants\"\u003eConstants\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#unions\"\u003eUnions\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#lists-and-simple-kinds\"\u003eLists and Simple kinds\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#differing-representations\"\u003eDiffering Representations\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#verbs-on-resources\"\u003eVerbs on Resources\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#patch-operations\"\u003ePATCH operations\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#short-names-and-categories\"\u003eShort-names and Categories\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#short-names\"\u003eShort-names\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#categories\"\u003eCategories\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#idempotency\"\u003eIdempotency\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#optional-vs-required\"\u003eOptional vs. Required\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#defaulting\"\u003eDefaulting\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#static-defaults\"\u003eStatic Defaults\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#admission-controlled-defaults\"\u003eAdmission Controlled Defaults\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#controller-assigned-defaults-aka-late-initialization\"\u003eController-Assigned Defaults (aka Late Initialization)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#what-may-be-defaulted\"\u003eWhat May Be Defaulted\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#considerations-for-put-operations\"\u003eConsiderations For PUT Operations\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#concurrency-control-and-consistency\"\u003eConcurrency Control and Consistency\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#serialization-format\"\u003eSerialization Format\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#units\"\u003eUnits\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#selecting-fields\"\u003eSelecting Fields\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#object-references\"\u003eObject references\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#naming-of-the-reference-field\"\u003eNaming of the reference field\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#referencing-resources-with-multiple-versions\"\u003eReferencing resources with multiple versions\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#handling-of-resources-that-do-not-exist\"\u003eHandling of resources that do not exist\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#validation-of-fields\"\u003eValidation of fields\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#do-not-modify-the-referred-object\"\u003eDo not modify the referred object\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#minimize-copying-or-printing-values-to-the-referrer-object\"\u003eMinimize copying or printing values to the referrer object\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#object-references-examples\"\u003eObject References Examples\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#single-resource-reference\"\u003eSingle resource reference\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#controller-behavior\"\u003eController behavior\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#multiple-resource-reference\"\u003eMultiple resource reference\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#kind-vs-resource\"\u003eKind vs. Resource\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#controller-behavior-1\"\u003eController behavior\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#generic-object-reference\"\u003eGeneric object reference\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#controller-behavior-2\"\u003eController behavior\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#field-reference\"\u003eField reference\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#controller-behavior-3\"\u003eController behavior\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#http-status-codes\"\u003eHTTP Status codes\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#success-codes\"\u003eSuccess codes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#error-codes\"\u003eError codes\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#response-status-kind\"\u003eResponse Status Kind\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#events\"\u003eEvents\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#naming-conventions\"\u003eNaming conventions\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#namespace-names\"\u003eNamespace Names\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#label-selector-and-annotation-conventions\"\u003eLabel, selector, and annotation conventions\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#websockets-and-spdy\"\u003eWebSockets and SPDY\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#validation\"\u003eValidation\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#automatic-resource-allocation-and-deallocation\"\u003eAutomatic Resource Allocation And Deallocation\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#representing-allocated-values\"\u003eRepresenting Allocated Values\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#when-to-use-a-spec-field\"\u003eWhen to use a \u003ccode\u003espec\u003c/code\u003e field\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#when-to-use-a-status-field\"\u003eWhen to use a \u003ccode\u003estatus\u003c/code\u003e field\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#sequencing-operations\"\u003eSequencing operations\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#when-to-use-a-different-type\"\u003eWhen to use a different type\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThe conventions of the \u003ca href=\"https://kubernetes.io/docs/concepts/overview/kubernetes-api/\" rel=\"nofollow\"\u003eKubernetes API\u003c/a\u003e (and related APIs in the\necosystem) are intended to ease client development and ensure that configuration\nmechanisms can be implemented that work across a diverse set of use cases\nconsistently.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe general style of the Kubernetes API is RESTful - clients create, update,\ndelete, or retrieve a description of an object via the standard HTTP verbs\n(POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return\nJSON. Kubernetes also exposes additional endpoints for non-standard verbs and\nallows alternative content types. All of the JSON accepted and returned by the\nserver has a schema, identified by the \"kind\" and \"apiVersion\" fields. Where\nrelevant HTTP header fields exist, they should mirror the content of JSON\nfields, but the information should not be represented only in the HTTP header.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe following terms are defined:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eKind\u003c/strong\u003e the name of a particular object schema (e.g. the \"Cat\" and \"Dog\"\nkinds would have different attributes and properties)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eResource\u003c/strong\u003e a representation of a system entity, sent or retrieved as JSON\nvia HTTP to the server. Resources are exposed via:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eCollections - a list of resources of the same type, which may be queryable\u003c/li\u003e\n\u003cli\u003eElements - an individual resource, addressable via a URL\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAPI Group\u003c/strong\u003e a set of resources that are exposed together, along\nwith the version exposed in the \"apiVersion\" field as \"GROUP/VERSION\", e.g.\n\"policy.k8s.io/v1\".\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eEach resource typically accepts and returns data of a single kind. A kind may be\naccepted or returned by multiple resources that reflect specific use cases. For\ninstance, the kind \"Pod\" is exposed as a \"pods\" resource that allows end users\nto create, update, and delete pods, while a separate \"pod status\" resource (that\nacts on \"Pod\" kind) allows automated processes to update a subset of the fields\nin that resource.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eResources are bound together in API groups - each group may have one or more\nversions that evolve independent of other API groups, and each version within\nthe group has one or more resources. Group names are typically in domain name\nform - the Kubernetes project reserves use of the empty group, all single\nword names (\"extensions\", \"apps\"), and any group name ending in \"*.k8s.io\" for\nits sole use. When choosing a group name, we recommend selecting a subdomain\nyour group or organization owns, such as \"widget.mycompany.com\".\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eVersion strings should match\n\u003ca href=\"https://git.k8s.io/design-proposals-archive/architecture/identifiers.md\" rel=\"nofollow\"\u003eDNS_LABEL\u003c/a\u003e\nformat.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eResource collections should be all lowercase and plural, whereas kinds are\nCamelCase and singular. Group names must be lower case and be valid DNS\nsubdomains.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTypes (Kinds)\u003c/h2\u003e\u003ca id=\"user-content-types-kinds\" class=\"anchor\" aria-label=\"Permalink: Types (Kinds)\" href=\"#types-kinds\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eKinds are grouped into three categories:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eObjects\u003c/strong\u003e represent a persistent entity in the system.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCreating an API object is a record of intent - once created, the system will\nwork to ensure that resource exists. All API objects have common metadata.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAn object may have multiple resources that clients can use to perform\nspecific actions that create, update, delete, or get.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eExamples: \u003ccode\u003ePod\u003c/code\u003e, \u003ccode\u003eReplicationController\u003c/code\u003e, \u003ccode\u003eService\u003c/code\u003e, \u003ccode\u003eNamespace\u003c/code\u003e, \u003ccode\u003eNode\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eLists\u003c/strong\u003e are collections of \u003cstrong\u003eresources\u003c/strong\u003e of one (usually) or more\n(occasionally) kinds.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe name of a list kind must end with \"List\". Lists have a limited set of\ncommon metadata. All lists use the required \"items\" field to contain the array\nof objects they return. Any kind that has the \"items\" field must be a list kind.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMost objects defined in the system should have an endpoint that returns the\nfull set of resources, as well as zero or more endpoints that return subsets of\nthe full list. Some objects may be singletons (the current user, the system\ndefaults) and may not have lists.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn addition, all lists that return objects with labels should support label\nfiltering (see \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\" rel=\"nofollow\"\u003ethe labels documentation\u003c/a\u003e),\nand most lists should support filtering by fields (see\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/\" rel=\"nofollow\"\u003ethe fields documentation\u003c/a\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eExamples: \u003ccode\u003ePodList\u003c/code\u003e, \u003ccode\u003eServiceList\u003c/code\u003e, \u003ccode\u003eNodeList\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eNote that\u003ccode\u003ekubectl\u003c/code\u003e and other tools sometimes output collections of resources\nas \u003ccode\u003ekind: List\u003c/code\u003e. Keep in mind that \u003ccode\u003ekind: List\u003c/code\u003e is not part of the Kubernetes API; it is\nexposing an implementation detail from client-side code in those tools, used to\nhandle groups of mixed resources.\u003c/p\u003e\n\u003col start=\"3\" dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eSimple\u003c/strong\u003e kinds are used for specific actions on objects and for\nnon-persistent entities.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eGiven their limited scope, they have the same set of limited common metadata\nas lists.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor instance, the \"Status\" kind is returned when errors occur and is not\npersisted in the system.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMany simple resources are \"subresources\", which are rooted at API paths of\nspecific resources. When resources wish to expose alternative actions or views\nthat are closely coupled to a single resource, they should do so using new\nsub-resources. Common subresources include:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e/binding\u003c/code\u003e: Used to bind a resource representing a user request (e.g., Pod,\nPersistentVolumeClaim) to a cluster infrastructure resource (e.g., Node,\nPersistentVolume).\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/status\u003c/code\u003e: Used to write just the \u003ccode\u003estatus\u003c/code\u003e portion of a resource. For\nexample, the \u003ccode\u003e/pods\u003c/code\u003e endpoint only allows updates to \u003ccode\u003emetadata\u003c/code\u003e and \u003ccode\u003espec\u003c/code\u003e,\nsince those reflect end-user intent. An automated process should be able to\nmodify status for users to see by sending an updated Pod kind to the server to\nthe \"/pods/\u0026lt;name\u0026gt;/status\" endpoint - the alternate endpoint allows\ndifferent rules to be applied to the update, and access to be appropriately\nrestricted.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/scale\u003c/code\u003e: Used to read and write the count of a resource in a manner that\nis independent of the specific resource schema.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eTwo additional subresources, \u003ccode\u003eproxy\u003c/code\u003e and \u003ccode\u003eportforward\u003c/code\u003e, provide access to\ncluster resources as described in\n\u003ca href=\"https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/\" rel=\"nofollow\"\u003eaccessing the cluster\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eThe standard REST verbs (defined below) MUST return singular JSON objects. Some\nAPI endpoints may deviate from the strict REST pattern and return resources that\nare not singular JSON objects, such as streams of JSON objects or unstructured\ntext log data.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA common set of \"meta\" API objects are used across all API groups and are\nthus considered part of the API group named \u003ccode\u003emeta.k8s.io\u003c/code\u003e. These types may\nevolve independent of the API group that uses them and API servers may allow\nthem to be addressed in their generic form. Examples are \u003ccode\u003eListOptions\u003c/code\u003e,\n\u003ccode\u003eDeleteOptions\u003c/code\u003e, \u003ccode\u003eList\u003c/code\u003e, \u003ccode\u003eStatus\u003c/code\u003e, \u003ccode\u003eWatchEvent\u003c/code\u003e, and \u003ccode\u003eScale\u003c/code\u003e. For historical\nreasons these types are part of each existing API group. Generic tools like\nquota, garbage collection, autoscalers, and generic clients like kubectl\nleverage these types to define consistent behavior across different resource\ntypes, like the interfaces in programming languages.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe term \"kind\" is reserved for these \"top-level\" API types. The term \"type\"\nshould be used for distinguishing sub-categories within objects or subobjects.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eResources\u003c/h3\u003e\u003ca id=\"user-content-resources\" class=\"anchor\" aria-label=\"Permalink: Resources\" href=\"#resources\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll JSON objects returned by an API MUST have the following fields:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ekind: a string that identifies the schema this object should have\u003c/li\u003e\n\u003cli\u003eapiVersion: a string that identifies the version of the schema the object\nshould have\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThese fields are required for proper decoding of the object. They may be\npopulated by the server by default from the specified URL path, but the client\nlikely needs to know the values in order to construct the URL path.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eObjects\u003c/h3\u003e\u003ca id=\"user-content-objects\" class=\"anchor\" aria-label=\"Permalink: Objects\" href=\"#objects\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMetadata\u003c/h4\u003e\u003ca id=\"user-content-metadata\" class=\"anchor\" aria-label=\"Permalink: Metadata\" href=\"#metadata\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEvery object kind MUST have the following metadata in a nested object field\ncalled \"metadata\":\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003enamespace: a namespace is a DNS compatible label that objects are subdivided\ninto. The default namespace is 'default'. See\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\" rel=\"nofollow\"\u003ethe namespace docs\u003c/a\u003e for more.\u003c/li\u003e\n\u003cli\u003ename: a string that uniquely identifies this object within the current\nnamespace (see \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\" rel=\"nofollow\"\u003ethe identifiers docs\u003c/a\u003e).\nThis value is used in the path when retrieving an individual object.\u003c/li\u003e\n\u003cli\u003euid: a unique in time and space value (typically an RFC 4122 generated\nidentifier, see \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\" rel=\"nofollow\"\u003ethe identifiers docs\u003c/a\u003e)\nused to distinguish between objects with the same name that have been deleted\nand recreated\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eEvery object SHOULD have the following metadata in a nested object field called\n\"metadata\":\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eresourceVersion: a string that identifies the internal version of this object\nthat can be used by clients to determine when objects have changed. This value\nMUST be treated as opaque by clients and passed unmodified back to the server.\nClients should not assume that the resource version has meaning across\nnamespaces, different kinds of resources, or different servers. (See\n\u003ca href=\"#concurrency-control-and-consistency\"\u003econcurrency control\u003c/a\u003e, below, for more\ndetails.)\u003c/li\u003e\n\u003cli\u003egeneration: a sequence number representing a specific generation of the\ndesired state. Set by the system and monotonically increasing, per-resource. May\nbe compared, such as for RAW and WAW consistency.\u003c/li\u003e\n\u003cli\u003ecreationTimestamp: a string representing an RFC 3339 date of the date and time\nan object was created\u003c/li\u003e\n\u003cli\u003edeletionTimestamp: a string representing an RFC 3339 date of the date and time\nafter which this resource will be deleted. This field is set by the server when\na graceful deletion is requested by the user, and is not directly settable by a\nclient. The resource will be deleted (no longer visible from resource lists, and\nnot reachable by name) after the time in this field except when the object has\na finalizer set. In case the finalizer is set the deletion of the object is\npostponed at least until the finalizer is removed.\nOnce the deletionTimestamp is set, this value may not be unset or be set further\ninto the future, although it may be shortened or the resource may be deleted\nprior to this time.\u003c/li\u003e\n\u003cli\u003elabels: a map of string keys and values that can be used to organize and\ncategorize objects (see \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\" rel=\"nofollow\"\u003ethe labels docs\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eannotations: a map of string keys and values that can be used by external\ntooling to store and retrieve arbitrary metadata about this object (see\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\" rel=\"nofollow\"\u003ethe annotations docs\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eLabels are intended for organizational purposes by end users (select the pods\nthat match this label query). Annotations enable third-party automation and\ntooling to decorate objects with additional metadata for their own use.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSpec and Status\u003c/h4\u003e\u003ca id=\"user-content-spec-and-status\" class=\"anchor\" aria-label=\"Permalink: Spec and Status\" href=\"#spec-and-status\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBy convention, the Kubernetes API makes a distinction between the specification\nof the desired state of an object (a nested object field called \u003ccode\u003espec\u003c/code\u003e) and the\nstatus of the object at the current time (a nested object field called\n\u003ccode\u003estatus\u003c/code\u003e). The specification is a complete description of the desired state,\nincluding configuration settings provided by the user,\n\u003ca href=\"#defaulting\"\u003edefault values\u003c/a\u003e expanded by the system, and properties initialized\nor otherwise changed after creation by other ecosystem components (e.g.,\nschedulers, auto-scalers), and is persisted in stable storage with the API\nobject. If the specification is deleted, the object will be purged from the\nsystem.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003estatus\u003c/code\u003e summarizes the current state of the object in the system, and is\nusually persisted with the object by automated processes but may be generated\non the fly. As a general guideline, fields in \u003ccode\u003estatus\u003c/code\u003e should be the most recent\nobservations of actual state, but they may contain information such as the\nresults of allocations or similar operations which are executed in response to\nthe object's \u003ccode\u003espec\u003c/code\u003e. See \u003ca href=\"#representing-allocated-values\"\u003ebelow\u003c/a\u003e for more\ndetails.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTypes with both \u003ccode\u003espec\u003c/code\u003e and \u003ccode\u003estatus\u003c/code\u003e stanzas can (and usually should) have distinct\nauthorization scopes for them. This allows users to be granted full write\naccess to \u003ccode\u003espec\u003c/code\u003e and read-only access to status, while relevant controllers are\ngranted read-only access to \u003ccode\u003espec\u003c/code\u003e but full write access to status.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen a new version of an object is POSTed or PUT, the \u003ccode\u003espec\u003c/code\u003e is updated and\navailable immediately. Over time the system will work to bring the \u003ccode\u003estatus\u003c/code\u003e into\nline with the \u003ccode\u003espec\u003c/code\u003e. The system will drive toward the most recent \u003ccode\u003espec\u003c/code\u003e\nregardless of previous versions of that stanza. For example, if a value is\nchanged from 2 to 5 in one PUT and then back down to 3 in another PUT the system\nis not required to 'touch base' at 5 before changing the \u003ccode\u003estatus\u003c/code\u003e to 3. In other\nwords, the system's behavior is \u003cem\u003elevel-based\u003c/em\u003e rather than \u003cem\u003eedge-based\u003c/em\u003e. This\nenables robust behavior in the presence of missed intermediate state changes.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe Kubernetes API also serves as the foundation for the declarative\nconfiguration schema for the system. In order to facilitate level-based\noperation and expression of declarative configuration, fields in the\nspecification should have declarative rather than imperative names and\nsemantics -- they represent the desired state, not actions intended to yield the\ndesired state.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe PUT and POST verbs on objects MUST ignore the \u003ccode\u003estatus\u003c/code\u003e values, to avoid\naccidentally overwriting the \u003ccode\u003estatus\u003c/code\u003e in read-modify-write scenarios. A \u003ccode\u003e/status\u003c/code\u003e\nsubresource MUST be provided to enable system components to update statuses of\nresources they manage.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOtherwise, PUT expects the whole object to be specified. Therefore, if a field\nis omitted it is assumed that the client wants to clear that field's value. The\nPUT verb does not accept partial updates. Modification of just part of an object\nmay be achieved by GETting the resource, modifying part of the spec, labels, or\nannotations, and then PUTting it back. See\n\u003ca href=\"#concurrency-control-and-consistency\"\u003econcurrency control\u003c/a\u003e, below, regarding\nread-modify-write consistency when using this pattern. Some objects may expose\nalternative resource representations that allow mutation of the status, or\nperforming custom actions on the object.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAll objects that represent a physical resource whose state may vary from the\nuser's desired intent SHOULD have a \u003ccode\u003espec\u003c/code\u003e and a \u003ccode\u003estatus\u003c/code\u003e. Objects whose state\ncannot vary from the user's desired intent MAY have only \u003ccode\u003espec\u003c/code\u003e, and MAY rename\n\u003ccode\u003espec\u003c/code\u003e to a more appropriate name.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eObjects that contain both \u003ccode\u003espec\u003c/code\u003e and \u003ccode\u003estatus\u003c/code\u003e should not contain additional\ntop-level fields other than the standard metadata fields.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSome objects which are not persisted in the system - such as \u003ccode\u003eSubjectAccessReview\u003c/code\u003e\nand other webhook style calls - may choose to add \u003ccode\u003espec\u003c/code\u003e and \u003ccode\u003estatus\u003c/code\u003e to encapsulate\na \"call and response\" pattern. The \u003ccode\u003espec\u003c/code\u003e is the request (often a request for\ninformation) and the \u003ccode\u003estatus\u003c/code\u003e is the response. For these RPC like objects the only\noperation may be POST, but having a consistent schema between submission and\nresponse reduces the complexity of these clients.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTypical status properties\u003c/h5\u003e\u003ca id=\"user-content-typical-status-properties\" class=\"anchor\" aria-label=\"Permalink: Typical status properties\" href=\"#typical-status-properties\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eConditions\u003c/strong\u003e provide a standard mechanism for higher-level status reporting\nfrom a controller. They are an extension mechanism which allows tools and other\ncontrollers to collect summary information about resources without needing to\nunderstand resource-specific status details. Conditions should complement more\ndetailed information about the observed status of an object written by a\ncontroller, rather than replace it. For example, the \"Available\" condition of a\nDeployment can be determined by examining \u003ccode\u003ereadyReplicas\u003c/code\u003e, \u003ccode\u003ereplicas\u003c/code\u003e, and\nother properties of the Deployment. However, the \"Available\" condition allows\nother components to avoid duplicating the availability logic in the Deployment\ncontroller.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eObjects may report multiple conditions, and new types of conditions may be\nadded in the future or by 3rd party controllers. Therefore, conditions are\nrepresented using a list/slice of objects, where each condition has a similar\nstructure. This collection should be treated as a map with a key of \u003ccode\u003etype\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eConditions are most useful when they follow some consistent conventions:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eConditions should be added to explicitly convey properties that users and\ncomponents care about rather than requiring those properties to be inferred\nfrom other observations. Once defined, the meaning of a Condition can not be\nchanged arbitrarily - it becomes part of the API, and has the same backwards-\nand forwards-compatibility concerns of any other part of the API.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eControllers should apply their conditions to a resource the first time they\nvisit the resource, even if the \u003ccode\u003estatus\u003c/code\u003e is Unknown. This allows other\ncomponents in the system to know that the condition exists and the controller\nis making progress on reconciling that resource.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNot all controllers will observe the previous advice about reporting\n\"Unknown\" or \"False\" values. For known conditions, the absence of a\ncondition \u003ccode\u003estatus\u003c/code\u003e should be interpreted the same as \u003ccode\u003eUnknown\u003c/code\u003e, and\ntypically indicates that reconciliation has not yet finished (or that the\nresource state may not yet be observable).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eFor some conditions, \u003ccode\u003eTrue\u003c/code\u003e represents normal operation, and for some\nconditions, \u003ccode\u003eFalse\u003c/code\u003e represents normal operation. (\"Normal-true\" conditions\nare sometimes said to have \"positive polarity\", and \"normal-false\" conditions\nare said to have \"negative polarity\".) Without further knowledge of the\nconditions, it is not possible to compute a generic summary of the conditions\non a resource.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eCondition type names should make sense for humans; neither positive nor\nnegative polarity can be recommended as a general rule. A negative condition\nlike \"MemoryExhausted\" may be easier for humans to understand than\n\"SufficientMemory\". Conversely, \"Ready\" or \"Succeeded\" may be easier to\nunderstand than \"Failed\", because \"Failed=Unknown\" or \"Failed=False\" may\ncause double-negative confusion.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eCondition type names should describe the current observed state of the\nresource, rather than describing the current state transitions. This\ntypically means that the name should be an adjective (\"Ready\", \"OutOfDisk\")\nor a past-tense verb (\"Succeeded\", \"Failed\") rather than a present-tense verb\n(\"Deploying\"). Intermediate states may be indicated by setting the \u003ccode\u003estatus\u003c/code\u003e of\nthe condition to \u003ccode\u003eUnknown\u003c/code\u003e.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor state transitions which take a long period of time (e.g. more than 1\nminute), it is reasonable to treat the transition itself as an observed\nstate. In these cases, the Condition (such as \"Resizing\") itself should not\nbe transient, and should instead be signalled using the\n\u003ccode\u003eTrue\u003c/code\u003e/\u003ccode\u003eFalse\u003c/code\u003e/\u003ccode\u003eUnknown\u003c/code\u003e pattern. This allows other observers to determine\nthe last update from the controller, whether successful or failed. In cases\nwhere the state transition is unable to complete and continued\nreconciliation is not feasible, the Reason and Message should be used to\nindicate that the transition failed.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eWhen designing Conditions for a resource, it's helpful to have a common\ntop-level condition which summarizes more detailed conditions. Simple\nconsumers may simply query the top-level condition. Although they are not a\nconsistent standard, the \u003ccode\u003eReady\u003c/code\u003e and \u003ccode\u003eSucceeded\u003c/code\u003e condition types may be used\nby API designers for long-running and bounded-execution objects, respectively.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eConditions should follow the standard schema included in \u003ca href=\"https://github.com/kubernetes/apimachinery/blob/release-1.23/pkg/apis/meta/v1/types.go#L1432-L1492\"\u003ek8s.io/apimachinery/pkg/apis/meta/v1/types.go\u003c/a\u003e.\nIt should be included as a top level element in status, similar to\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-go notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// +listType=map\n// +listMapKey=type\n// +patchStrategy=merge\n// +patchMergeKey=type\n// +optional\nConditions []metav1.Condition `json:\u0026quot;conditions,omitempty\u0026quot; patchStrategy:\u0026quot;merge\u0026quot; patchMergeKey:\u0026quot;type\u0026quot; protobuf:\u0026quot;bytes,1,rep,name=conditions\u0026quot;`\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e// +listType=map\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +listMapKey=type\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +patchStrategy=merge\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +patchMergeKey=type\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +optional\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eConditions\u003c/span\u003e []metav1.\u003cspan class=\"pl-smi\"\u003eCondition\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003emetav1.Conditions\u003c/code\u003e includes the following fields\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-go notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// type of condition in CamelCase or in foo.example.com/CamelCase.\n// +required\nType string `json:\u0026quot;type\u0026quot; protobuf:\u0026quot;bytes,1,opt,name=type\u0026quot;`\n// status of the condition, one of True, False, Unknown.\n// +required\nStatus ConditionStatus `json:\u0026quot;status\u0026quot; protobuf:\u0026quot;bytes,2,opt,name=status\u0026quot;`\n// observedGeneration represents the .metadata.generation that the condition was set based upon.\n// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n// with respect to the current state of the instance.\n// +optional\nObservedGeneration int64 `json:\u0026quot;observedGeneration,omitempty\u0026quot; protobuf:\u0026quot;varint,3,opt,name=observedGeneration\u0026quot;`\n// lastTransitionTime is the last time the condition transitioned from one status to another.\n// This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.\n// +required\nLastTransitionTime Time `json:\u0026quot;lastTransitionTime\u0026quot; protobuf:\u0026quot;bytes,4,opt,name=lastTransitionTime\u0026quot;`\n// reason contains a programmatic identifier indicating the reason for the condition's last transition.\n// Producers of specific condition types may define expected values and meanings for this field,\n// and whether the values are considered a guaranteed API.\n// The value should be a CamelCase string.\n// This field may not be empty.\n// +required\nReason string `json:\u0026quot;reason\u0026quot; protobuf:\u0026quot;bytes,5,opt,name=reason\u0026quot;`\n// message is a human readable message indicating details about the transition.\n// This may be an empty string.\n// +required\nMessage string `json:\u0026quot;message\u0026quot; protobuf:\u0026quot;bytes,6,opt,name=message\u0026quot;`\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e// type of condition in CamelCase or in foo.example.com/CamelCase.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +required\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eType\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003estring\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"type\" protobuf:\"bytes,1,opt,name=type\"`\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// status of the condition, one of True, False, Unknown.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +required\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eStatus\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eConditionStatus\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"status\" protobuf:\"bytes,2,opt,name=status\"`\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// observedGeneration represents the .metadata.generation that the condition was set based upon.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// with respect to the current state of the instance.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +optional\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eObservedGeneration\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eint64\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"observedGeneration,omitempty\" protobuf:\"varint,3,opt,name=observedGeneration\"`\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// lastTransitionTime is the last time the condition transitioned from one status to another.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +required\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eLastTransitionTime\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eTime\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"lastTransitionTime\" protobuf:\"bytes,4,opt,name=lastTransitionTime\"`\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// reason contains a programmatic identifier indicating the reason for the condition's last transition.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// Producers of specific condition types may define expected values and meanings for this field,\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// and whether the values are considered a guaranteed API.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// The value should be a CamelCase string.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// This field may not be empty.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +required\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eReason\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003estring\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"reason\" protobuf:\"bytes,5,opt,name=reason\"`\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// message is a human readable message indicating details about the transition.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// This may be an empty string.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// +required\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eMessage\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003estring\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e`json:\"message\" protobuf:\"bytes,6,opt,name=message\"`\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAdditional fields may be added in the future.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eUse of the \u003ccode\u003eReason\u003c/code\u003e field is required.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCondition types should be named in PascalCase. Short condition names are\npreferred (e.g. \"Ready\" over \"MyResourceReady\").\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCondition \u003ccode\u003estatus\u003c/code\u003e values may be \u003ccode\u003eTrue\u003c/code\u003e, \u003ccode\u003eFalse\u003c/code\u003e, or \u003ccode\u003eUnknown\u003c/code\u003e. The absence of a\ncondition should be interpreted the same as \u003ccode\u003eUnknown\u003c/code\u003e. How controllers handle\n\u003ccode\u003eUnknown\u003c/code\u003e depends on the Condition in question.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe thinking around conditions has evolved over time, so there are several\nnon-normative examples in wide use.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn general, condition values may change back and forth, but some condition\ntransitions may be monotonic, depending on the resource and condition type.\nHowever, conditions are observations and not, themselves, state machines, nor do\nwe define comprehensive state machines for objects, nor behaviors associated\nwith state transitions. The system is level-based rather than edge-triggered,\nand should assume an Open World.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAn example of an oscillating condition type is \u003ccode\u003eReady\u003c/code\u003e, which indicates the\nobject was believed to be fully operational at the time it was last probed. A\npossible monotonic condition could be \u003ccode\u003eSucceeded\u003c/code\u003e. A \u003ccode\u003eTrue\u003c/code\u003e status for\n\u003ccode\u003eSucceeded\u003c/code\u003e would imply completion and that the resource was no longer\nactive. An object that was still active would generally have a \u003ccode\u003eSucceeded\u003c/code\u003e\ncondition with status \u003ccode\u003eUnknown\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSome resources in the v1 API contain fields called \u003cstrong\u003e\u003ccode\u003ephase\u003c/code\u003e\u003c/strong\u003e, and associated\n\u003ccode\u003emessage\u003c/code\u003e, \u003ccode\u003ereason\u003c/code\u003e, and other status fields. The pattern of using \u003ccode\u003ephase\u003c/code\u003e is\ndeprecated. Newer API types should use conditions instead. Phase was\nessentially a state-machine enumeration field, that contradicted \u003ca href=\"https://git.k8s.io/design-proposals-archive/architecture/principles.md#control-logic\" rel=\"nofollow\"\u003esystem-design\nprinciples\u003c/a\u003e and\nhampered evolution, since \u003ca href=\"/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md\"\u003eadding new enum values breaks backward\ncompatibility\u003c/a\u003e. Rather than encouraging clients to infer\nimplicit properties from phases, we prefer to explicitly expose the individual\nconditions that clients need to monitor. Conditions also have the benefit that\nit is possible to create some conditions with uniform meaning across all\nresource types, while still exposing others that are unique to specific\nresource types. See \u003ca href=\"http://issues.k8s.io/7856\" rel=\"nofollow\"\u003e#7856\u003c/a\u003e for more details and\ndiscussion.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn condition types, and everywhere else they appear in the API, \u003cstrong\u003e\u003ccode\u003eReason\u003c/code\u003e\u003c/strong\u003e is\nintended to be a one-word, CamelCase representation of the category of cause of\nthe current status, and \u003cstrong\u003e\u003ccode\u003eMessage\u003c/code\u003e\u003c/strong\u003e is intended to be a human-readable phrase\nor sentence, which may contain specific details of the individual occurrence.\n\u003ccode\u003eReason\u003c/code\u003e is intended to be used in concise output, such as one-line\n\u003ccode\u003ekubectl get\u003c/code\u003e output, and in summarizing occurrences of causes, whereas\n\u003ccode\u003eMessage\u003c/code\u003e is intended to be presented to users in detailed status explanations,\nsuch as \u003ccode\u003ekubectl describe\u003c/code\u003e output.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHistorical information status (e.g., last transition time, failure counts) is\nonly provided with reasonable effort, and is not guaranteed to not be lost.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eStatus information that may be large (especially proportional in size to\ncollections of other resources, such as lists of references to other objects --\nsee below) and/or rapidly changing, such as\n\u003ca href=\"https://git.k8s.io/design-proposals-archive/scheduling/resources.md#usage-data\" rel=\"nofollow\"\u003eresource usage\u003c/a\u003e, should be put into separate\nobjects, with possibly a reference from the original object. This helps to\nensure that GETs and watch remain reasonably efficient for the majority of\nclients, which may not need that data.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSome resources report the \u003ccode\u003eobservedGeneration\u003c/code\u003e, which is the \u003ccode\u003egeneration\u003c/code\u003e most\nrecently observed by the component responsible for acting upon changes to the\ndesired state of the resource. This can be used, for instance, to ensure that\nthe reported status reflects the most recent desired status.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eReferences to related objects\u003c/h4\u003e\u003ca id=\"user-content-references-to-related-objects\" class=\"anchor\" aria-label=\"Permalink: References to related objects\" href=\"#references-to-related-objects\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eReferences to loosely coupled sets of objects, such as\n\u003ca href=\"https://kubernetes.io/docs/concepts/workloads/pods/\" rel=\"nofollow\"\u003epods\u003c/a\u003e overseen by a\n\u003ca href=\"https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/\" rel=\"nofollow\"\u003ereplication controller\u003c/a\u003e,\nare usually best referred to using a\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors\" rel=\"nofollow\"\u003elabel selector\u003c/a\u003e. In order to\nensure that GETs of individual objects remain bounded in time and space, these\nsets may be queried via separate API queries, but will not be expanded in the\nreferring object's status.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor references to specific objects, see \u003ca href=\"#object-references\"\u003eObject references\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eReferences in the \u003ccode\u003estatus\u003c/code\u003e of the referee to the referrer may be permitted, when\nthe references are one-to-one and do not need to be frequently updated,\nparticularly in an edge-based manner.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLists of named subobjects preferred over maps\u003c/h4\u003e\u003ca id=\"user-content-lists-of-named-subobjects-preferred-over-maps\" class=\"anchor\" aria-label=\"Permalink: Lists of named subobjects preferred over maps\" href=\"#lists-of-named-subobjects-preferred-over-maps\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eDiscussed in \u003ca href=\"http://issue.k8s.io/2004\" rel=\"nofollow\"\u003e#2004\u003c/a\u003e and elsewhere. There are\nno maps of subobjects in any API objects. Instead, the convention is to\nuse a list of subobjects containing name fields. These conventions, and\nhow one can change the semantics of lists, structs and maps are\ndescribed in more details in the Kubernetes\n\u003ca href=\"https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy\" rel=\"nofollow\"\u003edocumentation\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"ports:\n - name: www\n containerPort: 80\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003eports\u003c/span\u003e:\n - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewww\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003econtainerPort\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e80\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003evs.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"ports:\n www:\n containerPort: 80\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003eports\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003ewww\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003econtainerPort\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e80\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis rule maintains the invariant that all JSON/YAML keys are fields in API\nobjects. The only exceptions are pure maps in the API (currently, labels,\nselectors, annotations, data), as opposed to sets of subobjects.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePrimitive types\u003c/h4\u003e\u003ca id=\"user-content-primitive-types\" class=\"anchor\" aria-label=\"Permalink: Primitive types\" href=\"#primitive-types\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eLook at similar fields in the API (e.g. ports, durations) and follow the\nconventions of existing fields.\u003c/li\u003e\n\u003cli\u003eDo not use enums. Use aliases for string instead (e.g. \u003ccode\u003eNodeConditionType\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eAll numeric fields should be bounds-checked, both for too-small or negative\nand for too-large.\u003c/li\u003e\n\u003cli\u003eAll public integer fields MUST use the Go \u003ccode\u003eint32\u003c/code\u003e or Go \u003ccode\u003eint64\u003c/code\u003e types, not\n\u003ccode\u003eint\u003c/code\u003e (which is ambiguously sized, depending on target platform). Internal\ntypes may use \u003ccode\u003eint\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eFor integer fields, prefer \u003ccode\u003eint32\u003c/code\u003e to \u003ccode\u003eint64\u003c/code\u003e unless you need to represent\nvalues larger than \u003ccode\u003eint32\u003c/code\u003e. See other guidelines about limitations of\n\u003ccode\u003eint64\u003c/code\u003e and language compatibility.\u003c/li\u003e\n\u003cli\u003eDo not use unsigned integers, due to inconsistent support across languages and\nlibraries. Just validate that the integer is non-negative if that's the case.\u003c/li\u003e\n\u003cli\u003eAll numbers (e.g. \u003ccode\u003eint32\u003c/code\u003e, \u003ccode\u003eint64\u003c/code\u003e) are converted to \u003ccode\u003efloat64\u003c/code\u003e by Javascript\nand some other languages, so any field which is expected to exceed that\neither in magnitude or in precision (e.g. integer values \u0026gt; 53 bits)\nshould be serialized and accepted as strings. \u003ccode\u003eint64\u003c/code\u003e fields must be\nbounds-checked to be within the range of \u003ccode\u003e-(2^53) \u0026lt; x \u0026lt; (2^53)\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAvoid floating-point values as much as possible, and never use them in spec.\nFloating-point values cannot be reliably round-tripped (encoded and\nre-decoded) without changing, and have varying precision and representations\nacross languages and architectures.\u003c/li\u003e\n\u003cli\u003eThink twice about \u003ccode\u003ebool\u003c/code\u003e fields. Many ideas start as boolean but eventually\ntrend towards a small set of mutually exclusive options. Plan for future\nexpansions by describing the policy options explicitly as a string type\nalias (e.g. \u003ccode\u003eTerminationMessagePolicy\u003c/code\u003e).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConstants\u003c/h4\u003e\u003ca id=\"user-content-constants\" class=\"anchor\" aria-label=\"Permalink: Constants\" href=\"#constants\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSome fields will have a list of allowed values (enumerations). These values will\nbe strings, and they will be in CamelCase, with an initial uppercase letter.\nExamples: \u003ccode\u003eClusterFirst\u003c/code\u003e, \u003ccode\u003ePending\u003c/code\u003e, \u003ccode\u003eClientIP\u003c/code\u003e. When an acronym or initialism\neach letter in the acronym should be uppercase, such as with \u003ccode\u003eClientIP\u003c/code\u003e or\n\u003ccode\u003eTCPDelay\u003c/code\u003e. When a proper name or the name of a command-line executable is used\nas a constant the proper name should be represented in consistent casing -\nexamples: \u003ccode\u003esystemd\u003c/code\u003e, \u003ccode\u003eiptables\u003c/code\u003e, \u003ccode\u003eIPVS\u003c/code\u003e, \u003ccode\u003ecgroupfs\u003c/code\u003e, \u003ccode\u003eDocker\u003c/code\u003e (as a generic\nconcept), \u003ccode\u003edocker\u003c/code\u003e (as the command-line executable). If a proper name is used\nwhich has mixed capitalization like \u003ccode\u003eeBPF\u003c/code\u003e that should be preserved in a longer\nconstant such as \u003ccode\u003eeBPFDelegation\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAll API within Kubernetes must leverage constants in this style, including\nflags and configuration files. Where inconsistent constants were previously used,\nnew flags should be CamelCase only, and over time old flags should be updated to\naccept a CamelCase value alongside the inconsistent constant. Example: the\nKubelet accepts a \u003ccode\u003e--topology-manager-policy\u003c/code\u003e flag that has values \u003ccode\u003enone\u003c/code\u003e,\n\u003ccode\u003ebest-effort\u003c/code\u003e, \u003ccode\u003erestricted\u003c/code\u003e, and \u003ccode\u003esingle-numa-node\u003c/code\u003e. This flag should accept\n\u003ccode\u003eNone\u003c/code\u003e, \u003ccode\u003eBestEffort\u003c/code\u003e, \u003ccode\u003eRestricted\u003c/code\u003e, and \u003ccode\u003eSingleNUMANode\u003c/code\u003e going forward. If new\nvalues are added to the flag, both forms should be supported.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUnions\u003c/h4\u003e\u003ca id=\"user-content-unions\" class=\"anchor\" aria-label=\"Permalink: Unions\" href=\"#unions\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSometimes, at most one of a set of fields can be set. For example, the\n[volumes] field of a PodSpec has 17 different volume type-specific fields, such\nas \u003ccode\u003enfs\u003c/code\u003e and \u003ccode\u003eiscsi\u003c/code\u003e. All fields in the set should be\n\u003ca href=\"#optional-vs-required\"\u003eOptional\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSometimes, when a new type is created, the api designer may anticipate that a\nunion will be needed in the future, even if only one field is allowed initially.\nIn this case, be sure to make the field \u003ca href=\"#optional-vs-required\"\u003eOptional\u003c/a\u003e\nIn the validation, you may still return an error if the sole field is unset. Do\nnot set a default value for that field.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLists and Simple kinds\u003c/h3\u003e\u003ca id=\"user-content-lists-and-simple-kinds\" class=\"anchor\" aria-label=\"Permalink: Lists and Simple kinds\" href=\"#lists-and-simple-kinds\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEvery list or simple kind SHOULD have the following metadata in a nested object\nfield called \"metadata\":\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eresourceVersion: a string that identifies the common version of the objects\nreturned by in a list. This value MUST be treated as opaque by clients and\npassed unmodified back to the server. A resource version is only valid within a\nsingle namespace on a single kind of resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eEvery simple kind returned by the server, and any simple kind sent to the server\nthat must support idempotency or optimistic concurrency should return this\nvalue. Since simple resources are often used as input alternate actions that\nmodify objects, the resource version of the simple resource should correspond to\nthe resource version of the object.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDiffering Representations\u003c/h2\u003e\u003ca id=\"user-content-differing-representations\" class=\"anchor\" aria-label=\"Permalink: Differing Representations\" href=\"#differing-representations\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAn API may represent a single entity in different ways for different clients, or\ntransform an object after certain transitions in the system occur. In these\ncases, one request object may have two representations available as different\nresources, or different kinds.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAn example is a Service, which represents the intent of the user to group a set\nof pods with common behavior on common ports. When Kubernetes detects a pod\nmatches the service selector, the IP address and port of the pod are added to an\nEndpoints resource for that Service. The Endpoints resource exists only if the\nService exists, but exposes only the IPs and ports of the selected pods. The\nfull service is represented by two distinct resources - under the original\nService resource the user created, as well as in the Endpoints resource.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAs another example, a \"pod status\" resource may accept a PUT with the \"pod\"\nkind, with different rules about what fields may be changed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFuture versions of Kubernetes may allow alternative encodings of objects beyond\nJSON.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVerbs on Resources\u003c/h2\u003e\u003ca id=\"user-content-verbs-on-resources\" class=\"anchor\" aria-label=\"Permalink: Verbs on Resources\" href=\"#verbs-on-resources\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAPI resources should use the traditional REST pattern:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eGET /\u0026lt;resourceNamePlural\u0026gt; - Retrieve a list of type\n\u0026lt;resourceName\u0026gt;, e.g. GET /pods returns a list of Pods.\u003c/li\u003e\n\u003cli\u003ePOST /\u0026lt;resourceNamePlural\u0026gt; - Create a new resource from the JSON object\nprovided by the client.\u003c/li\u003e\n\u003cli\u003eGET /\u0026lt;resourceNamePlural\u0026gt;/\u0026lt;name\u0026gt; - Retrieves a single resource\nwith the given name, e.g. GET /pods/first returns a Pod named 'first'. Should be\nconstant time, and the resource should be bounded in size.\u003c/li\u003e\n\u003cli\u003eDELETE /\u0026lt;resourceNamePlural\u0026gt;/\u0026lt;name\u0026gt; - Delete the single resource\nwith the given name. DeleteOptions may specify gracePeriodSeconds, the optional\nduration in seconds before the object should be deleted. Individual kinds may\ndeclare fields which provide a default grace period, and different kinds may\nhave differing kind-wide default grace periods. A user provided grace period\noverrides a default grace period, including the zero grace period (\"now\").\u003c/li\u003e\n\u003cli\u003eDELETE /\u0026lt;resourceNamePlural\u0026gt; - Deletes a list of type\n\u0026lt;resourceName\u0026gt;, e.g. DELETE /pods a list of Pods.\u003c/li\u003e\n\u003cli\u003ePUT /\u0026lt;resourceNamePlural\u0026gt;/\u0026lt;name\u0026gt; - Update or create the resource\nwith the given name with the JSON object provided by the client. Whether a\nresource can be created with a PUT request depends on the particular resource's\nstorage strategy configuration, specifically the \u003ccode\u003eAllowCreateOnUpdate()\u003c/code\u003e return\nvalue. Most built-in types do not allow this.\u003c/li\u003e\n\u003cli\u003ePATCH /\u0026lt;resourceNamePlural\u0026gt;/\u0026lt;name\u0026gt; - Selectively modify the\nspecified fields of the resource. See more information \u003ca href=\"#patch-operations\"\u003ebelow\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eGET /\u0026lt;resourceNamePlural\u0026gt;?watch=true - Receive a stream of JSON\nobjects corresponding to changes made to any resource of the given kind over\ntime.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePATCH operations\u003c/h3\u003e\u003ca id=\"user-content-patch-operations\" class=\"anchor\" aria-label=\"Permalink: PATCH operations\" href=\"#patch-operations\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe API supports three different PATCH operations, determined by their\ncorresponding Content-Type header:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eJSON Patch, \u003ccode\u003eContent-Type: application/json-patch+json\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAs defined in \u003ca href=\"https://tools.ietf.org/html/rfc6902\" rel=\"nofollow\"\u003eRFC6902\u003c/a\u003e, a JSON Patch is\na sequence of operations that are executed on the resource, e.g. \u003ccode\u003e{\"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ]}\u003c/code\u003e. For more details on how to use\nJSON Patch, see the RFC.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eMerge Patch, \u003ccode\u003eContent-Type: application/merge-patch+json\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAs defined in \u003ca href=\"https://tools.ietf.org/html/rfc7386\" rel=\"nofollow\"\u003eRFC7386\u003c/a\u003e, a Merge Patch\nis essentially a partial representation of the resource. The submitted JSON is\n\"merged\" with the current resource to create a new one, then the new one is\nsaved. For more details on how to use Merge Patch, see the RFC.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eStrategic Merge Patch, \u003ccode\u003eContent-Type: application/strategic-merge-patch+json\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eStrategic Merge Patch is a custom implementation of Merge Patch. For a\ndetailed explanation of how it works and why it needed to be introduced, see\n\u003ca href=\"/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md\"\u003ehere\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eShort-names and Categories\u003c/h2\u003e\u003ca id=\"user-content-short-names-and-categories\" class=\"anchor\" aria-label=\"Permalink: Short-names and Categories\" href=\"#short-names-and-categories\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eResource implementers can optionally include \"short names\" and categories\nin the discovery information published for a resource type,\nwhich clients may use as hints when resolving ambiguous user invocations.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor compiled-in resources, these are controlled by the REST handler \u003ccode\u003eShortNames() []string\u003c/code\u003e and \u003ccode\u003eCategories() []string\u003c/code\u003e implementations.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor custom resources, these are controlled by the \u003ccode\u003e.spec.names.shortNames\u003c/code\u003e and \u003ccode\u003e.spec.names.categories\u003c/code\u003e fields in the CustomResourceDefinition.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eShort-names\u003c/h3\u003e\u003ca id=\"user-content-short-names\" class=\"anchor\" aria-label=\"Permalink: Short-names\" href=\"#short-names\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNote: Due to unpredictable behavior when short names collide (with each other or with resource types),\ndo not add new short names to built-in resources unless specifically allowed by API reviewers. See issues\n\u003ca href=\"https://issue.k8s.io/117742#issuecomment-1545945336\" rel=\"nofollow\"\u003e#117742\u003c/a\u003e and \u003ca href=\"http://issue.k8s.io/108573\" rel=\"nofollow\"\u003e#108573\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\"Short names\" listed in discovery may be used by clients as hints to resolve ambiguous user invocations to a single resource.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eExamples of built-in short names include:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eds\u003c/code\u003e -\u0026gt; \u003ccode\u003eapps/v* daemonsets\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ests\u003c/code\u003e -\u0026gt; \u003ccode\u003eapps/v* statefulsets\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehpa\u003c/code\u003e -\u0026gt; \u003ccode\u003eautoscaling/v* horizontalpodautoscalers\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eFor example, with only built-in API types served, \u003ccode\u003ekubectl get sts\u003c/code\u003e is equivalent to \u003ccode\u003ekubectl get statefulsets.v1.apps\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eShort-name matches may be given lower priority than an exact match of a resource type,\nso use of short names increases potential for inconsistent behavior in clusters\nwith custom resources installed, if those custom resource types overlap with short names.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eContinuing the above example, if a custom resource with \u003ccode\u003e.spec.names.plural\u003c/code\u003e set to \u003ccode\u003ests\u003c/code\u003e was installed in a cluster,\n\u003ccode\u003ekubectl get sts\u003c/code\u003e would switch to retrieving instances of the custom resource instead.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCategories\u003c/h3\u003e\u003ca id=\"user-content-categories\" class=\"anchor\" aria-label=\"Permalink: Categories\" href=\"#categories\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNote: Due to inconsistent behavior when categories collide with resource types,\nand difficulties knowing when it is safe to add new resources to an existing category,\ndo not add new categories to built-in resources unless specifically allowed by API reviewers.\nSee issues \u003ca href=\"https://github.com/kubernetes/kubernetes/issues/7547#issuecomment-355835279\" data-hovercard-type=\"issue\" data-hovercard-url=\"/kubernetes/kubernetes/issues/7547/hovercard\"\u003e#7547\u003c/a\u003e\n\u003ca href=\"https://github.com/kubernetes/kubernetes/issues/42885#issuecomment-531265679\" data-hovercard-type=\"issue\" data-hovercard-url=\"/kubernetes/kubernetes/issues/42885/hovercard\"\u003e#42885\u003c/a\u003e,\nand \u003ca href=\"https://github.com/kubernetes/community/blob/master/contributors/devel/sig-cli/kubectl-conventions.md#rules-for-extending-special-resource-alias---all\"\u003econsiderations for adding to the \"all\" category\u003c/a\u003e\nfor examples of the difficulties encountered.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCategories listed in discovery may be used by clients as hints to resolve user invocations to multiple resources.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eExamples of built-in categories and the resources they map to include:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eapi-extensions\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eapiregistration.k8s.io/v* apiservices\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadmissionregistration.k8s.io/v* mutatingwebhookconfigurations\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadmissionregistration.k8s.io/v* validatingwebhookconfigurations\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadmissionregistration.k8s.io/v* validatingadmissionpolicies\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadmissionregistration.k8s.io/v* validatingadmissionpolicybindings\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eapiextensions.k8s.io/v* customresourcedefinitions\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eall\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ev1 pods\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ev1 replicationcontrollers\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ev1 services\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eapps/v* daemonsets\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eapps/v* deployments\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eapps/v* replicasets\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eapps/v* statefulsets\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eautoscaling/v* horizontalpodautoscalers\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ebatch/v* cronjobs\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ebatch/v* jobs\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eWith the above categories, and only built-in API types served, \u003ccode\u003ekubectl get all\u003c/code\u003e would be equivalent to\n\u003ccode\u003ekubectl get pods.v1.,replicationcontrollers.v1.,services.v1.,daemonsets.v1.apps,deployments.v1.apps,replicasets.v1.apps,statefulsets.v1.apps,horizontalpodautoscalers.v2.autoscaling,cronjobs.v1.batch,jobs.v1.batch,\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eIdempotency\u003c/h2\u003e\u003ca id=\"user-content-idempotency\" class=\"anchor\" aria-label=\"Permalink: Idempotency\" href=\"#idempotency\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll compatible Kubernetes APIs MUST support \"name idempotency\" and respond with\nan HTTP status code 409 when a request is made to POST an object that has the\nsame name as an existing object in the system. See\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\" rel=\"nofollow\"\u003ethe identifiers docs\u003c/a\u003e\nfor details.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNames generated by the system may be requested using \u003ccode\u003emetadata.generateName\u003c/code\u003e.\nGenerateName indicates that the name should be made unique by the server prior\nto persisting it. A non-empty value for the field indicates the server should\nattempt to make the name unique (and the name returned to the client will be\ndifferent than the name passed). The value of this field will be combined with a\nrandom suffix on the server if the Name field has not been provided. The\nprovided value must be valid within the rules for Name, and may be truncated by\nthe length of the suffix. If this field is specified, and Name is not present,\nthe server will return a 409 with Reason \u003ccode\u003eAlreadyExists\u003c/code\u003e if the generated name\nexists, and the client should retry (after waiting at least the amount of time\nindicated in the Retry-After header, if it is present).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eOptional vs. Required\u003c/h2\u003e\u003ca id=\"user-content-optional-vs-required\" class=\"anchor\" aria-label=\"Permalink: Optional vs. Required\" href=\"#optional-vs-required\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFields must be either optional or required.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOptional fields have the following properties:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThey have the \u003ccode\u003e+optional\u003c/code\u003e comment tag in Go.\u003c/li\u003e\n\u003cli\u003eThey are a pointer type in the Go definition (e.g. \u003ccode\u003eAwesomeFlag *SomeFlag\u003c/code\u003e) or\nhave a built-in \u003ccode\u003enil\u003c/code\u003e value (e.g. maps and slices).\u003c/li\u003e\n\u003cli\u003eThe API server should allow POSTing and PUTing a resource with this field\nunset.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eIn most cases, optional fields should also have the \u003ccode\u003eomitempty\u003c/code\u003e struct tag (the\n\u003ccode\u003eomitempty\u003c/code\u003e option specifies that the field should be omitted from the json\nencoding if the field has an empty value). However, If you want to have\ndifferent logic for an optional field which is not provided vs. provided with\nempty values, do not use \u003ccode\u003eomitempty\u003c/code\u003e (e.g. \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"182620092\" data-permission-text=\"Title is private\" data-url=\"https://github.com/kubernetes/kubernetes/issues/34641\" data-hovercard-type=\"issue\" data-hovercard-url=\"/kubernetes/kubernetes/issues/34641/hovercard\" href=\"https://github.com/kubernetes/kubernetes/issues/34641\"\u003ekubernetes/kubernetes#34641\u003c/a\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNote that for backward compatibility, any field that has the \u003ccode\u003eomitempty\u003c/code\u003e struct\ntag will be considered to be optional, but this may change in the future and\nhaving the \u003ccode\u003e+optional\u003c/code\u003e comment tag is highly recommended.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRequired fields have the opposite properties, namely:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThey do not have an \u003ccode\u003e+optional\u003c/code\u003e comment tag.\u003c/li\u003e\n\u003cli\u003eThey do not have an \u003ccode\u003eomitempty\u003c/code\u003e struct tag.\u003c/li\u003e\n\u003cli\u003eThey are not a pointer type in the Go definition (e.g. \u003ccode\u003eAnotherFlag SomeFlag\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eThe API server should not allow POSTing or PUTing a resource with this field\nunset.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eUsing the \u003ccode\u003e+optional\u003c/code\u003e or the \u003ccode\u003eomitempty\u003c/code\u003e tag causes OpenAPI documentation to\nreflect that the field is optional.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eUsing a pointer allows distinguishing unset from the zero value for that type.\nThere are some cases where, in principle, a pointer is not needed for an\noptional field since the zero value is forbidden, and thus implies unset. There\nare examples of this in the codebase. However:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eit can be difficult for implementors to anticipate all cases where an empty\nvalue might need to be distinguished from a zero value\u003c/li\u003e\n\u003cli\u003estructs are not omitted from encoder output even where omitempty is specified,\nwhich is messy;\u003c/li\u003e\n\u003cli\u003ehaving a pointer consistently imply optional is clearer for users of the Go\nlanguage client, and any other clients that use corresponding types\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eTherefore, we ask that pointers always be used with optional fields that do not\nhave a built-in \u003ccode\u003enil\u003c/code\u003e value.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDefaulting\u003c/h2\u003e\u003ca id=\"user-content-defaulting\" class=\"anchor\" aria-label=\"Permalink: Defaulting\" href=\"#defaulting\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn general we want default values to be explicitly represented in our APIs,\nrather than asserting that \"unspecified fields get the default behavior\". This\nis important so that:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003edefault values can evolve and change in newer API versions\u003c/li\u003e\n\u003cli\u003ethe stored configuration depicts the full desired state, making it easier\nfor the system to determine how to achieve the state, and for the user to\nknow what to anticipate\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThere are 3 distinct ways that default values can be applied when creating or\nupdating (including patch and apply) a resource:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003estatic: based on the requested API version and possibly other fields in the\nresource, fields can be assigned values during the API call\u003c/li\u003e\n\u003cli\u003eadmission control: based on the configured admission controllers and\npossibly other state in or out of the cluster, fields can be assigned\nvalues during the API call\u003c/li\u003e\n\u003cli\u003econtrollers: arbitrary changes (within the bounds of what is allowed) can\nbe made to a resource after the API call has completed\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eSome care is required when deciding which mechanism to use and managing the\nsemantics.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStatic Defaults\u003c/h3\u003e\u003ca id=\"user-content-static-defaults\" class=\"anchor\" aria-label=\"Permalink: Static Defaults\" href=\"#static-defaults\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStatic default values are specific to each API version. The default field\nvalues applied when creating an object with the \"v1\" API may be different than\nthe values applied when using the \"v2\" API. In most cases, these values are\ndefined as literal values by the API version (e.g. \"if this field is not\nspecified it defaults to 0\").\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn some cases, these values may be conditional on or deterministically derived\nfrom other fields (e.g. \"if otherField is X then this field defaults to 0\" or\n\"this field defaults to the value of otherField\"). Note that such derived\ndefaults present a hazard in the face of updates - if the \"other\" field\nchanges, the derived field may have to change, too. The static defaulting\nlogic is unaware of updates and has no concept of \"previous value\", which means\nthis inter-field relationship becomes the user's problem - they must update\nboth the field they care about and the \"other\" field.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn very rare cases, these values may be allocated from some pool or determined\nby some other method (e.g. Service's IP and IP-family related fields need to\nconsider other configuration settings).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThese values are applied synchronously by the API server when decoding\nversioned data. For CREATE and UPDATE operations this is fairly\nstraight-forward - when the API server receives a (versioned) request, the\ndefault values are immediately applied before any further processing. When the\nAPI call completes, all static defaults will have been set and stored.\nSubsequent GETs of the resource will include the default values explicitly.\nHowever, static defaults also apply when an object is read from storage (i.e.\nGET operations). This means that when someone GETs an \"older\" stored object,\nany fields which have been added to the API since that object was stored will\nbe defaulted and returned according to the API version that is stored.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eStatic defaults are the best choice for values which are logically required,\nbut which have a value that works well for most users. Static defaulting\nmust not consider any state except the object being operated upon (and the\ncomplexity of Service API stands as an example of why).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDefault values can be specified on a field using the \u003ccode\u003e+default=\u003c/code\u003e tag. Primitives\nwill have their values directly assigned while structs will go through the\nJSON unmarshalling process. Fields that do not have an \u003ccode\u003eomitempty\u003c/code\u003e json tag will\ndefault to the zero value of their corresponding type if no default is assigned.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRefer to \u003ca href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting\" rel=\"nofollow\"\u003edefaulting docs\u003c/a\u003e\nfor more information.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAdmission Controlled Defaults\u003c/h3\u003e\u003ca id=\"user-content-admission-controlled-defaults\" class=\"anchor\" aria-label=\"Permalink: Admission Controlled Defaults\" href=\"#admission-controlled-defaults\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn some cases, it is useful to set a default value which is not derived from\nthe object in question. For example, when creating a PersistentVolumeClaim,\nthe storage class must be specified. For many users, the best answer is\n\"whatever the cluster admin has decided for the default\". StorageClass is a\ndifferent API than PersistentVolumeClaim, and which one is denoted as the\ndefault may change at any time. Thus this is not eligible for static\ndefaulting.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eInstead, we can provide a built-in admission controller or a\nMutatingWebhookConfiguration. Unlike static defaults, these may consider\nexternal state (such as annotations on StorageClass objects) when deciding\ndefault values, and must handle things like race conditions (e.g. a\nStorageClass is designated the default, but the admission controller has not\nyet seen that update). These admission controllers are strictly optional and\ncan be disabled. As such, fields which are initialized this way must be\nstrictly optional.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLike static defaults, these are run synchronously to the API operation in\nquestion, and when the API call completes, all static defaults will have been\nset. Subsequent GETs of the resource will include the default values\nexplicitly.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController-Assigned Defaults (aka Late Initialization)\u003c/h3\u003e\u003ca id=\"user-content-controller-assigned-defaults-aka-late-initialization\" class=\"anchor\" aria-label=\"Permalink: Controller-Assigned Defaults (aka Late Initialization)\" href=\"#controller-assigned-defaults-aka-late-initialization\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eLate initialization is when resource fields are set by a system controller\nafter an object is created/updated (asynchronously). For example, the\nscheduler sets the \u003ccode\u003epod.spec.nodeName\u003c/code\u003e field after the pod is created. It's\na stretch to call this \"defaulting\" but since it is so common and useful, it is\nincluded here.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLike admission controlled defaults, these controllers may consider external\nstate when deciding what values to set, must handle race conditions, and can be\ndisabled. Fields which are initialized this way must be strictly optional\n(meaning observers will see the object without these fields set, and that is\nallowable and semantically correct).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLike all controllers, care must be taken to not clobber unrelated fields or\nvalues (e.g. in an array). Using one of the patch or apply mechanisms is\nrecommended to facilitate composition and concurrency of controllers.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhat May Be Defaulted\u003c/h3\u003e\u003ca id=\"user-content-what-may-be-defaulted\" class=\"anchor\" aria-label=\"Permalink: What May Be Defaulted\" href=\"#what-may-be-defaulted\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll forms of defaulting should only make the following types of modifications:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSetting previously unset fields\u003c/li\u003e\n\u003cli\u003eAdding keys to maps\u003c/li\u003e\n\u003cli\u003eAdding values to arrays which have mergeable semantics\n(\u003ccode\u003e+listType=map\u003c/code\u003e tag or \u003ccode\u003epatchStrategy:\"merge\"\u003c/code\u003e attribute in the type definition)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eIn particular we never want to change or override a value that was provided by\nthe user. If they requested something invalid, they should get an error.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThese rules ensure that:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003ea user (with sufficient privilege) can override any system-default\nbehaviors by explicitly setting the fields that would otherwise have been\ndefaulted\u003c/li\u003e\n\u003cli\u003eupdates from users can be merged with default values\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConsiderations For PUT Operations\u003c/h3\u003e\u003ca id=\"user-content-considerations-for-put-operations\" class=\"anchor\" aria-label=\"Permalink: Considerations For PUT Operations\" href=\"#considerations-for-put-operations\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOnce an object has been created and defaults have been applied, it's very\ncommon for updates to happen over time. Kubernetes offers several ways of\nupdating an object which preserve existing values in fields other than those\nbeing updated (e.g. strategic merge patch and server-side apply). There is,\nhowever, a less obvious way of updating objects which can have bad interactions\nwith default values - PUT (aka \u003ccode\u003ekubectl replace\u003c/code\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe goal is that, for a given input (e.g. YAML file), PUT on an existing object\nshould produce the same result as if you used that input to create the object.\nCalling PUT a second time with the same input should be idempotent and should\nnot change the resource. Even a read-modify-write cycle is not a perfect\nsolution in the face of version skew.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen an object is updated with a PUT, the API server will see the \"old\" object\nwith previously assigned defaults and the \"new\" object with newly assigned\ndefaults. For static defaults this can be a problem if the CREATE and the PUT\nused different API versions. For example, \"v1\" of an API might default a field\nto \u003ccode\u003efalse\u003c/code\u003e, while \"v2\" defaults it to \u003ccode\u003etrue\u003c/code\u003e. If an object was created via API\nv1 (field = \u003ccode\u003efalse\u003c/code\u003e) and then replaced via API v2, the field will attempt to\nchange to \u003ccode\u003etrue\u003c/code\u003e. This can also be a problem when the values are allocated or\nderived from a source outside of the object in question (e.g. Service IPs).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor some APIs this is acceptable and actionable. For others, this may be\ndisallowed by validation. In the latter case, the user will get an error about\nan attempt to change a field which is not even present in their YAML. This is\nespecially dangerous when adding new fields - an older client may not even know\nabout the existence of the field, making even a read-modify-write cycle fail.\nWhile it is \"correct\" (in the sense that it is really what they asked for with\nPUT), it is not helpful and is a bad UX.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen adding a field with a static or admission controlled default, this must be\nconsidered. If the field is immutable after creation, consider adding logic to\nmanually \"patch\" the value from the \"old\" object into the \"new\" one when it has\nbeen \"unset\", rather than returning an error or allocating a different value\n(e.g. Service IPs). This will very often be what the user meant, even if it\nis not what they said. This may require setting the default in a different way\n(e.g. in the registry code which understands updates instead of in the\nversioned defaulting code which does not). Be careful to detect and report\nlegitimate errors where the \"new\" value is specified but is different from the\n\"old\" value.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor controller-defaulted fields, the situation is even more unpleasant.\nControllers do not have an opportunity to \"patch\" the value before the API\noperation is committed. If the \"unset\" value is allowed then it will be saved,\nand any watch clients will be notified. If the \"unset\" value is not allowed or\nmutations are otherwise disallowed, the user will get an error, and there's\nsimply nothing we can do about it.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConcurrency Control and Consistency\u003c/h2\u003e\u003ca id=\"user-content-concurrency-control-and-consistency\" class=\"anchor\" aria-label=\"Permalink: Concurrency Control and Consistency\" href=\"#concurrency-control-and-consistency\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eKubernetes leverages the concept of \u003cem\u003eresource versions\u003c/em\u003e to achieve optimistic\nconcurrency. All Kubernetes resources have a \"resourceVersion\" field as part of\ntheir metadata. This resourceVersion is a string that identifies the internal\nversion of an object that can be used by clients to determine when objects have\nchanged. When a record is about to be updated, its version is checked against a\npre-saved value, and if it doesn't match, the update fails with a StatusConflict\n(HTTP status code 409).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe resourceVersion is changed by the server every time an object is modified.\nIf resourceVersion is included with the PUT operation the system will verify\nthat there have not been other successful mutations to the resource during a\nread/modify/write cycle, by verifying that the current value of resourceVersion\nmatches the specified value.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe resourceVersion is currently backed by \u003ca href=\"https://etcd.io/docs/latest/learning/api/#key-value-pair\" rel=\"nofollow\"\u003eetcd's\nmod_revision\u003c/a\u003e.\nHowever, it's important to note that the application should \u003cem\u003enot\u003c/em\u003e rely on the\nimplementation details of the versioning system maintained by Kubernetes. We may\nchange the implementation of resourceVersion in the future, such as to change it\nto a timestamp or per-object counter.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe only way for a client to know the expected value of resourceVersion is to\nhave received it from the server in response to a prior operation, typically a\nGET. This value MUST be treated as opaque by clients and passed unmodified back\nto the server. Clients should not assume that the resource version has meaning\nacross namespaces, different kinds of resources, or different servers.\nCurrently, the value of resourceVersion is set to match etcd's sequencer. You\ncould think of it as a logical clock the API server can use to order requests.\nHowever, we expect the implementation of resourceVersion to change in the\nfuture, such as in the case we shard the state by kind and/or namespace, or port\nto another storage system.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn the case of a conflict, the correct client action at this point is to GET the\nresource again, apply the changes afresh, and try submitting again. This\nmechanism can be used to prevent races like the following:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"Client #1 Client #2\nGET Foo GET Foo\nSet Foo.Bar = \u0026quot;one\u0026quot; Set Foo.Baz = \u0026quot;two\u0026quot;\nPUT Foo PUT Foo\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eClient #1 Client #2\nGET Foo GET Foo\nSet Foo.Bar = \"one\" Set Foo.Baz = \"two\"\nPUT Foo PUT Foo\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen these sequences occur in parallel, either the change to Foo.Bar or the\nchange to Foo.Baz can be lost.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOn the other hand, when specifying the resourceVersion, one of the PUTs will\nfail, since whichever write succeeds changes the resourceVersion for Foo.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eresourceVersion may be used as a precondition for other operations (e.g., GET,\nDELETE) in the future, such as for read-after-write consistency in the presence\nof caching.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\"Watch\" operations specify resourceVersion using a query parameter. It is used\nto specify the point at which to begin watching the specified resources. This\nmay be used to ensure that no mutations are missed between a GET of a resource\n(or list of resources) and a subsequent Watch, even if the current version of\nthe resource is more recent. This is currently the main reason that list\noperations (GET on a collection) return resourceVersion.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSerialization Format\u003c/h2\u003e\u003ca id=\"user-content-serialization-format\" class=\"anchor\" aria-label=\"Permalink: Serialization Format\" href=\"#serialization-format\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAPIs may return alternative representations of any resource in response to an\nAccept header or under alternative endpoints, but the default serialization for\ninput and output of API responses MUST be JSON.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA protobuf encoding is also accepted for built-in resources. As proto is not\nself-describing, there is an envelope wrapper which describes the type of\nthe contents.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAll dates should be serialized as RFC3339 strings.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUnits\u003c/h2\u003e\u003ca id=\"user-content-units\" class=\"anchor\" aria-label=\"Permalink: Units\" href=\"#units\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUnits must either be explicit in the field name (e.g., \u003ccode\u003etimeoutSeconds\u003c/code\u003e), or\nmust be specified as part of the value (e.g., \u003ccode\u003eresource.Quantity\u003c/code\u003e). Which\napproach is preferred is TBD, though currently we use the \u003ccode\u003efooSeconds\u003c/code\u003e\nconvention for durations.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDuration fields must be represented as integer fields with units being\npart of the field name (e.g. \u003ccode\u003eleaseDurationSeconds\u003c/code\u003e). We don't use Duration\nin the API since that would require clients to implement go-compatible parsing.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSelecting Fields\u003c/h2\u003e\u003ca id=\"user-content-selecting-fields\" class=\"anchor\" aria-label=\"Permalink: Selecting Fields\" href=\"#selecting-fields\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSome APIs may need to identify which field in a JSON object is invalid, or to\nreference a value to extract from a separate resource. The current\nrecommendation is to use standard JavaScript syntax for accessing that field,\nassuming the JSON object was transformed into a JavaScript object, without the\nleading dot, such as \u003ccode\u003emetadata.name\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eExamples:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFind the field \"current\" in the object \"state\" in the second item in the array\n\"fields\": \u003ccode\u003efields[1].state.current\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eObject references\u003c/h2\u003e\u003ca id=\"user-content-object-references\" class=\"anchor\" aria-label=\"Permalink: Object references\" href=\"#object-references\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eObject references on a namespaced type should usually refer only to objects in\nthe same namespace. Because namespaces are a security boundary, cross namespace\nreferences can have unexpected impacts, including:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eleaking information about one namespace into another namespace. It's natural to place status messages or even bits of\ncontent about the referenced object in the original. This is a problem across namespaces.\u003c/li\u003e\n\u003cli\u003epotential invasions into other namespaces. Often references give access to a piece of referred information, so being\nable to express \"give me that one over there\" is dangerous across namespaces without additional work for permission checks\nor opt-in's from both involved namespaces.\u003c/li\u003e\n\u003cli\u003ereferential integrity problems that one party cannot solve. Referencing namespace/B from namespace/A doesn't imply the\npower to control the other namespace. This means that you can refer to a thing you cannot create or update.\u003c/li\u003e\n\u003cli\u003eunclear semantics on deletion. If a namespaced resource is referenced by other namespaces, should a delete of the\nreferenced resource result in removal or should the referenced resource be force to remain.\u003c/li\u003e\n\u003cli\u003eunclear semantics on creation. If a referenced resource is created after its reference, there is no way to know if it\nis the one that is expected or if it is a different one created with the same name.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eBuilt-in types and ownerReferences do not support cross namespaces references.\nIf a non-built-in types chooses to have cross-namespace references the semantics of the edge cases above should be\nclearly described and the permissions issues should be resolved.\nThis could be done with a double opt-in (an opt-in from both the referrer and the refer-ee) or with secondary permissions\nchecks performed in admission.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNaming of the reference field\u003c/h3\u003e\u003ca id=\"user-content-naming-of-the-reference-field\" class=\"anchor\" aria-label=\"Permalink: Naming of the reference field\" href=\"#naming-of-the-reference-field\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe name of the reference field should be of the format \"{field}Ref\", with \"Ref\" always included in the suffix.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \"{field}\" component should be named to indicate the purpose of the reference. For example, \"targetRef\" in an\nendpoint indicates that the object reference specifies the target.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt is okay to have the \"{field}\" component indicate the resource type. For example, \"secretRef\" when referencing\na secret. However, this comes with the risk of the field being a misnomer in the case that the field is expanded to\nreference more than one type.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn the case of a list of object references, the field should be of the format \"{field}Refs\", with the same guidance\nas the singular case above.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eReferencing resources with multiple versions\u003c/h3\u003e\u003ca id=\"user-content-referencing-resources-with-multiple-versions\" class=\"anchor\" aria-label=\"Permalink: Referencing resources with multiple versions\" href=\"#referencing-resources-with-multiple-versions\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMost resources will have multiple versions. For example, core resources\nwill undergo version changes as it transitions from alpha to GA.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eControllers should assume that a version of a resource may change, and include appropriate error handling.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHandling of resources that do not exist\u003c/h3\u003e\u003ca id=\"user-content-handling-of-resources-that-do-not-exist\" class=\"anchor\" aria-label=\"Permalink: Handling of resources that do not exist\" href=\"#handling-of-resources-that-do-not-exist\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThere are multiple scenarios where a desired resource may not exist. Examples include:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ethe desired version of the resource does not exist.\u003c/li\u003e\n\u003cli\u003erace condition in the bootstrapping of a cluster resulting a resource not yet added.\u003c/li\u003e\n\u003cli\u003euser error.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eControllers should be authored with the assumption that the referenced resource may not exist, and include\nerror handling to make the issue clear to the user.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eValidation of fields\u003c/h3\u003e\u003ca id=\"user-content-validation-of-fields\" class=\"anchor\" aria-label=\"Permalink: Validation of fields\" href=\"#validation-of-fields\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMany of the values used in an object reference are used as part of the API path. For example,\nthe object name is used in the path to identify the object. Unsanitized, these values can be used to\nattempt to retrieve other resources, such as by using values with semantic meanings such as \u003ccode\u003e..\u003c/code\u003e or \u003ccode\u003e/\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHave the controller validate fields before using them as path segments in an API request, and emit an event to\ntell the user that the validation has failed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSee \u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\" rel=\"nofollow\"\u003eObject Names and IDs\u003c/a\u003e\nfor more information on legal object names.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDo not modify the referred object\u003c/h3\u003e\u003ca id=\"user-content-do-not-modify-the-referred-object\" class=\"anchor\" aria-label=\"Permalink: Do not modify the referred object\" href=\"#do-not-modify-the-referred-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTo minimize potential privilege escalation vectors, do not modify the object that is being referred to,\nor limit modification to objects in the same namespace and constrain the type of modification allowed\n(for example, the HorizontalPodAutoscaler controller only writes to the \u003ccode\u003e/scale\u003c/code\u003e subresource).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMinimize copying or printing values to the referrer object\u003c/h3\u003e\u003ca id=\"user-content-minimize-copying-or-printing-values-to-the-referrer-object\" class=\"anchor\" aria-label=\"Permalink: Minimize copying or printing values to the referrer object\" href=\"#minimize-copying-or-printing-values-to-the-referrer-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs the permissions of the controller can differ from the permissions of the author of the object\nthe controller is managing, it is possible that the author of the object may not have permissions to\nview the referred object. As a result, the copying of any values about the referred object to the\nreferrer object can be considered permissions escalations, enabling a user to read values that they\nwould not have access to previously.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe same scenario applies to writing information about the referred object to events.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn general, do not write or print information retrieved from the referred object to the spec, other objects, or logs.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen it is necessary, consider whether these values would be ones that the\nauthor of the referrer object would have access to via other means (e.g. already required to\ncorrectly populate the object reference).\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eObject References Examples\u003c/h3\u003e\u003ca id=\"user-content-object-references-examples\" class=\"anchor\" aria-label=\"Permalink: Object References Examples\" href=\"#object-references-examples\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe following sections illustrate recommended schemas for various object references scenarios.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe schemas outlined below are designed to enable purely additive fields as the types of referencable\nobjects expand, and therefore are backwards compatible.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example, it is possible to go from a single resource type to multiple resource types without\na breaking change in the schema.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSingle resource reference\u003c/h4\u003e\u003ca id=\"user-content-single-resource-reference\" class=\"anchor\" aria-label=\"Permalink: Single resource reference\" href=\"#single-resource-reference\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA single kind object reference is straightforward in that the controller can hard-code most qualifiers needed to identify the object. As such as the only value needed to be provided is the name (and namespace, although cross-namespace references are discouraged):\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# for a single resource, the suffix should be Ref, with the field name\n# providing an indication as to the resource type referenced.\nsecretRef:\n name: foo\n # namespace would generally not be needed and is discouraged,\n # as explained above.\n namespace: foo-namespace\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e for a single resource, the suffix should be Ref, with the field name\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e providing an indication as to the resource type referenced.\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003esecretRef\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e namespace would generally not be needed and is discouraged,\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e as explained above.\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003enamespace\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo-namespace\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis schema should only be used when the intention is to always have the reference only be to a single resource.\nIf extending to multiple resource types is possible, use the \u003ca href=\"#multiple-resource-reference\"\u003emultiple resource reference\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController behavior\u003c/h5\u003e\u003ca id=\"user-content-controller-behavior\" class=\"anchor\" aria-label=\"Permalink: Controller behavior\" href=\"#controller-behavior\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe operator is expected to know the version, group, and resource name of the object it needs to retrieve the value from, and can use the discovery client or construct the API path directly.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMultiple resource reference\u003c/h4\u003e\u003ca id=\"user-content-multiple-resource-reference\" class=\"anchor\" aria-label=\"Permalink: Multiple resource reference\" href=\"#multiple-resource-reference\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMulti-kind object references are used when there is a bounded set of valid resource types that a reference can point to.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAs with a single-kind object reference, the operator can supply missing fields, provided that the fields that are present are sufficient to uniquely identify the object resource type among the set of supported types.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# guidance for the field name is the same as a single resource.\nfooRef:\n group: sns.services.k8s.aws\n resource: topics\n name: foo\n namespace: foo-namespace\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e guidance for the field name is the same as a single resource.\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003efooRef\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003egroup\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esns.services.k8s.aws\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003eresource\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etopics\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003enamespace\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo-namespace\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAlthough not always necessary to help a controller identify a resource type, “group” is included to avoid ambiguity when the resource exists in multiple groups. It also provides clarity to end users and enables copy-pasting of a reference without the referenced type changing due to a different controller handling the reference.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eKind vs. Resource\u003c/h5\u003e\u003ca id=\"user-content-kind-vs-resource\" class=\"anchor\" aria-label=\"Permalink: Kind vs. Resource\" href=\"#kind-vs-resource\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA common point of confusion in object references is whether to construct\nreferences with a \"kind\" or \"resource\" field. Historically most object\nreferences in Kubernetes have used \"kind\". This is not as precise as \"resource\".\nAlthough each combination of \"group\" and \"resource\" must be unique within\nKubernetes, the same is not always true for \"group\" and \"kind\". It is possible\nfor multiple resources to make use of the same \"kind\".\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTypically all objects in Kubernetes have a canonical primary resource - such as\n“pods” representing the way to create and delete resources of the “Pod” schema.\nWhile it is possible a resource schema cannot be directly created, such as a\n“Scale” object which is only used within the “scale” subresource of a number of\nworkloads, most object references address the primary resource via its schema.\nIn the context of object references, \"kind\" refers to the schema, not the\nresource.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf implementations of an object reference will always have a clear way to map\nkinds to resources, it is acceptable to use \"kind\" in the object reference. In\ngeneral, this requires implementations to have a predefined mapping between\nkinds and resources (this is the case for built-in references which use \"kind\").\nRelying on dynamic kind to resource mapping is not safe. Even if a \"kind\" only\ndynamically maps to a single resource initially, it's possible for another\nresource to be mounted that refers to the same \"kind\", potentially breaking any\ndynamic resource mapping.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf an object reference may be used to reference resources of arbitrary types and\nthe mapping between kind and resource could be ambiguous, \"resource\" should be\nused in the object reference.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe Ingress API provides a good example of where \"kind\" is acceptable for an\nobject reference. The API supports a backend reference as an extension point.\nImplementations can use this to support forwarding traffic to custom targets\nsuch as a storage bucket. Importantly, the supported target types are clearly\ndefined by each implementation of the API and there is no ambiguity for which\nresource a kind maps to. This is because each Ingress implementation has a\nhard-coded mapping of kind to resource.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe object reference above would look like this if it were using \"kind\" instead\nof \"resource\":\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"fooRef:\n group: sns.services.k8s.aws\n kind: Topic\n name: foo\n namespace: foo-namespace\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003efooRef\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003egroup\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esns.services.k8s.aws\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003ekind\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTopic\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003enamespace\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efoo-namespace\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController behavior\u003c/h5\u003e\u003ca id=\"user-content-controller-behavior-1\" class=\"anchor\" aria-label=\"Permalink: Controller behavior\" href=\"#controller-behavior-1\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe operator can store a map of (group,resource) to the version of that resource it desires. From there, it can construct the full path to the resource, and retrieve the object.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt is also possible to have the controller choose a version that it finds via the discovery client. However, as schemas can vary across different versions\nof a resource, the controller must also handle these differences.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGeneric object reference\u003c/h4\u003e\u003ca id=\"user-content-generic-object-reference\" class=\"anchor\" aria-label=\"Permalink: Generic object reference\" href=\"#generic-object-reference\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA generic object reference is used when the desire is to provide a pointer to some object to simplify discovery for the user. For example, this could be used to reference a target object for a \u003ccode\u003ecore.v1.Event\u003c/code\u003e that occurred.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWith a generic object reference, it is not possible to extract any information about the referenced object aside from what is standard (e.g. ObjectMeta). Since any standard fields exist in any version of a resource, it is possible to not include version in this case:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"fooObjectRef:\n group: operator.openshift.io\n resource: openshiftapiservers\n name: cluster\n # namespace is unset if the resource is cluster-scoped, or lives in the\n # same namespace as the referrer.\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003efooObjectRef\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003egroup\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eoperator.openshift.io\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003eresource\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eopenshiftapiservers\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecluster\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e namespace is unset if the resource is cluster-scoped, or lives in the\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e same namespace as the referrer.\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController behavior\u003c/h5\u003e\u003ca id=\"user-content-controller-behavior-2\" class=\"anchor\" aria-label=\"Permalink: Controller behavior\" href=\"#controller-behavior-2\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe operator would be expected to find the resource via the discovery client (as the version is not supplied). As any retrievable field would be common to all objects, any version of the resource should do.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eField reference\u003c/h4\u003e\u003ca id=\"user-content-field-reference\" class=\"anchor\" aria-label=\"Permalink: Field reference\" href=\"#field-reference\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA field reference is used when the desire is to extract a value from a specific field in a referenced object.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eField references differ from other reference types, as the operator has no knowledge of the object prior to the reference. Since the schema of an object can differ for different versions of a resource, this means that a “version” is required for this type of reference.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"fooFieldRef:\n version: v1 # version of the resource\n # group is elided in the ConfigMap example, since it has a blank group in the OpenAPI spec.\n resource: configmaps\n fieldPath: data.foo\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003efooFieldRef\u003c/span\u003e:\n \u003cspan class=\"pl-ent\"\u003eversion\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003ev1\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e version of the resource\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e group is elided in the ConfigMap example, since it has a blank group in the OpenAPI spec.\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003eresource\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003econfigmaps\u003c/span\u003e\n \u003cspan class=\"pl-ent\"\u003efieldPath\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edata.foo\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe fieldPath should point to a single value, and use \u003ca href=\"#selecting-fields\"\u003ethe recommended field selector notation\u003c/a\u003e to denote the field path.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController behavior\u003c/h5\u003e\u003ca id=\"user-content-controller-behavior-3\" class=\"anchor\" aria-label=\"Permalink: Controller behavior\" href=\"#controller-behavior-3\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn this scenario, the user will supply all of the required path elements: group, version, resource, name, and possibly namespace.\nAs such, the controller can construct the API prefix and query it without the use of the discovery client:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/apis/{group}/{version}/{resource}/\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e/apis/{group}/{version}/{resource}/\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHTTP Status codes\u003c/h2\u003e\u003ca id=\"user-content-http-status-codes\" class=\"anchor\" aria-label=\"Permalink: HTTP Status codes\" href=\"#http-status-codes\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe server will respond with HTTP status codes that match the HTTP spec. See the\nsection below for a breakdown of the types of status codes the server will send.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe following HTTP status codes may be returned by the API.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSuccess codes\u003c/h4\u003e\u003ca id=\"user-content-success-codes\" class=\"anchor\" aria-label=\"Permalink: Success codes\" href=\"#success-codes\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e200 StatusOK\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request completed successfully.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e201 StatusCreated\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request to create kind completed successfully.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e204 StatusNoContent\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request completed successfully, and the response contains\nno body.\u003c/li\u003e\n\u003cli\u003eReturned in response to HTTP OPTIONS requests.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eError codes\u003c/h4\u003e\u003ca id=\"user-content-error-codes\" class=\"anchor\" aria-label=\"Permalink: Error codes\" href=\"#error-codes\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e307 StatusTemporaryRedirect\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the address for the requested resource has changed.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFollow the redirect.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e400 StatusBadRequest\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates the requested is invalid.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e401 StatusUnauthorized\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\nrefuses to take any further action, because the client must provide\nauthorization. If the client has provided authorization, the server is\nindicating the provided authorization is unsuitable or invalid.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIf the user has not supplied authorization information, prompt them for\nthe appropriate credentials. If the user has supplied authorization information,\ninform them their credentials were rejected and optionally prompt them again.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e403 StatusForbidden\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\nrefuses to take any further action, because it is configured to deny access for\nsome reason to the requested resource by the client.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e404 StatusNotFound\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the requested resource does not exist.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e405 StatusMethodNotAllowed\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the action the client attempted to perform on the resource\nwas not supported by the code.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e409 StatusConflict\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that either the resource the client attempted to create already\nexists or the requested update operation cannot be completed due to a conflict.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIf creating a new resource:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eEither change the identifier and try again, or GET and compare the\nfields in the pre-existing object and issue a PUT/update to modify the existing\nobject.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eIf updating an existing resource:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSee \u003ccode\u003eConflict\u003c/code\u003e from the \u003ccode\u003estatus\u003c/code\u003e response section below on how to\nretrieve more information about the nature of the conflict.\u003c/li\u003e\n\u003cli\u003eGET and compare the fields in the pre-existing object, merge changes (if\nstill valid according to preconditions), and retry with the updated request\n(including \u003ccode\u003eResourceVersion\u003c/code\u003e).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e410 StatusGone\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the item is no longer available at the server and no\nforwarding address is known.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e422 StatusUnprocessableEntity\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the requested create or update operation cannot be completed\ndue to invalid data provided as part of the request.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDo not retry. Fix the request.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e429 StatusTooManyRequests\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that either the client rate limit has been exceeded or the\nserver has received more requests than it can process.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRead the \u003ccode\u003eRetry-After\u003c/code\u003e HTTP header from the response, and wait at least\nthat long before retrying.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e500 StatusInternalServerError\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\neither an unexpected internal error occurred and the outcome of the call is\nunknown, or the server cannot complete the action in a reasonable time (this may\nbe due to temporary server load or a transient communication issue with another\nserver).\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRetry with exponential backoff.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e503 StatusServiceUnavailable\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that required service is unavailable.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRetry with exponential backoff.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e504 StatusServerTimeout\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request could not be completed within the given time.\nClients can get this response ONLY when they specified a timeout param in the\nrequest.\u003c/li\u003e\n\u003cli\u003eSuggested client recovery behavior:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIncrease the value of the timeout param and retry with exponential\nbackoff.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eResponse Status Kind\u003c/h2\u003e\u003ca id=\"user-content-response-status-kind\" class=\"anchor\" aria-label=\"Permalink: Response Status Kind\" href=\"#response-status-kind\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eKubernetes will always return the \u003ccode\u003eStatus\u003c/code\u003e kind from any API endpoint when an\nerror occurs. Clients SHOULD handle these types of objects when appropriate.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA \u003ccode\u003eStatus\u003c/code\u003e kind will be returned by the API in two cases:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eWhen an operation is not successful (i.e. when the server would return a non\n2xx HTTP status code).\u003c/li\u003e\n\u003cli\u003eWhen a HTTP \u003ccode\u003eDELETE\u003c/code\u003e call is successful.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThe status object is encoded as JSON and provided as the body of the response.\nThe status object contains fields for humans and machine consumers of the API to\nget more detailed information for the cause of the failure. The information in\nthe status object supplements, but does not override, the HTTP status code's\nmeaning. When fields in the status object have the same meaning as generally\ndefined HTTP headers and that header is returned with the response, the header\nshould be considered as having higher priority.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eExample:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ curl -v -k -H \u0026quot;Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc\u0026quot; https://10.240.122.184:443/api/v1/namespaces/default/pods/grafana\n\n\u0026gt; GET /api/v1/namespaces/default/pods/grafana HTTP/1.1\n\u0026gt; User-Agent: curl/7.26.0\n\u0026gt; Host: 10.240.122.184\n\u0026gt; Accept: */*\n\u0026gt; Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc\n\u0026gt;\n\n\u0026lt; HTTP/1.1 404 Not Found\n\u0026lt; Content-Type: application/json\n\u0026lt; Date: Wed, 20 May 2015 18:10:42 GMT\n\u0026lt; Content-Length: 232\n\u0026lt;\n{\n \u0026quot;kind\u0026quot;: \u0026quot;Status\u0026quot;,\n \u0026quot;apiVersion\u0026quot;: \u0026quot;v1\u0026quot;,\n \u0026quot;metadata\u0026quot;: {},\n \u0026quot;status\u0026quot;: \u0026quot;Failure\u0026quot;,\n \u0026quot;message\u0026quot;: \u0026quot;pods \\\u0026quot;grafana\\\u0026quot; not found\u0026quot;,\n \u0026quot;reason\u0026quot;: \u0026quot;NotFound\u0026quot;,\n \u0026quot;details\u0026quot;: {\n \u0026quot;name\u0026quot;: \u0026quot;grafana\u0026quot;,\n \u0026quot;kind\u0026quot;: \u0026quot;pods\u0026quot;\n },\n \u0026quot;code\u0026quot;: 404\n}\"\u003e\u003cpre\u003e$ \u003cspan class=\"pl-s1\"\u003ecurl -v -k -H \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eAuthorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e https://10.240.122.184:443/api/v1/namespaces/default/pods/grafana\u003c/span\u003e\n\n\u0026gt; \u003cspan class=\"pl-s1\"\u003eGET /api/v1/namespaces/default/pods/grafana HTTP/1.1\u003c/span\u003e\n\u0026gt; \u003cspan class=\"pl-s1\"\u003eUser-Agent: curl/7.26.0\u003c/span\u003e\n\u0026gt; \u003cspan class=\"pl-s1\"\u003eHost: 10.240.122.184\u003c/span\u003e\n\u0026gt; \u003cspan class=\"pl-s1\"\u003eAccept: \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e/\u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e\u003c/span\u003e\n\u0026gt; \u003cspan class=\"pl-s1\"\u003eAuthorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc\u003c/span\u003e\n\u0026gt;\n\n\u003cspan class=\"pl-c1\"\u003e\u0026lt; HTTP/1.1 404 Not Found\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e\u0026lt; Content-Type: application/json\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e\u0026lt; Date: Wed, 20 May 2015 18:10:42 GMT\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e\u0026lt; Content-Length: 232\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"kind\": \"Status\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"apiVersion\": \"v1\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"metadata\": {},\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"status\": \"Failure\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"message\": \"pods \\\"grafana\\\" not found\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"reason\": \"NotFound\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"details\": {\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"name\": \"grafana\",\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"kind\": \"pods\"\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e \"code\": 404\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003estatus\u003c/code\u003e field contains one of two possible values:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eSuccess\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eFailure\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003emessage\u003c/code\u003e may contain human-readable description of the error\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003ereason\u003c/code\u003e may contain a machine-readable, one-word, CamelCase description of why\nthis operation is in the \u003ccode\u003eFailure\u003c/code\u003e status. If this value is empty there is no\ninformation available. The \u003ccode\u003ereason\u003c/code\u003e clarifies an HTTP status code but does not\noverride it.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003edetails\u003c/code\u003e may contain extended data associated with the reason. Each reason may\ndefine its own extended details. This field is optional and the data returned is\nnot guaranteed to conform to any schema except that defined by the reason type.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePossible values for the \u003ccode\u003ereason\u003c/code\u003e and \u003ccode\u003edetails\u003c/code\u003e fields:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eBadRequest\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request itself was invalid, because the request doesn't\nmake any sense, for example deleting a read-only object.\u003c/li\u003e\n\u003cli\u003eThis is different than \u003ccode\u003estatus reason\u003c/code\u003e \u003ccode\u003eInvalid\u003c/code\u003e above which indicates that\nthe API call could possibly succeed, but the data was invalid.\u003c/li\u003e\n\u003cli\u003eAPI calls that return BadRequest can never succeed.\u003c/li\u003e\n\u003cli\u003eHttp status code: \u003ccode\u003e400 StatusBadRequest\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eUnauthorized\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\nrefuses to take any further action without the client providing appropriate\nauthorization. If the client has provided authorization, this error indicates\nthe provided credentials are insufficient or invalid.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe kind attribute of the unauthorized resource (on some operations may\ndiffer from the requested resource).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe identifier of the unauthorized resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e401 StatusUnauthorized\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eForbidden\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\nrefuses to take any further action, because it is configured to deny access for\nsome reason to the requested resource by the client.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe kind attribute of the forbidden resource (on some operations may\ndiffer from the requested resource).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe identifier of the forbidden resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e403 StatusForbidden\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eNotFound\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that one or more resources required for this operation could not\nbe found.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe kind attribute of the missing resource (on some operations may\ndiffer from the requested resource).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe identifier of the missing resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e404 StatusNotFound\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eAlreadyExists\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the resource you are creating already exists.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe kind attribute of the conflicting resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe identifier of the conflicting resource.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e409 StatusConflict\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eConflict\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the requested update operation cannot be completed due to a\nconflict. The client may need to alter the request. Each resource may define\ncustom details that indicate the nature of the conflict.\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e409 StatusConflict\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eInvalid\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the requested create or update operation cannot be completed\ndue to invalid data provided as part of the request.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ethe kind attribute of the invalid resource\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ethe identifier of the invalid resource\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecauses\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOne or more \u003ccode\u003eStatusCause\u003c/code\u003e entries indicating the data in the provided\nresource that was invalid. The \u003ccode\u003ereason\u003c/code\u003e, \u003ccode\u003emessage\u003c/code\u003e, and \u003ccode\u003efield\u003c/code\u003e attributes will\nbe set.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHTTP status code: \u003ccode\u003e422 StatusUnprocessableEntity\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eTimeout\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the request could not be completed within the given time.\nClients may receive this response if the server has decided to rate limit the\nclient, or if the server is overloaded and cannot process the request at this\ntime.\u003c/li\u003e\n\u003cli\u003eHttp status code: \u003ccode\u003e429 TooManyRequests\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eThe server should set the \u003ccode\u003eRetry-After\u003c/code\u003e HTTP header and return\n\u003ccode\u003eretryAfterSeconds\u003c/code\u003e in the details field of the object. A value of \u003ccode\u003e0\u003c/code\u003e is the\ndefault.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eServerTimeout\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the server can be reached and understood the request, but\ncannot complete the action in a reasonable time. This maybe due to temporary\nserver load or a transient communication issue with another server.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ekind string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe kind attribute of the resource being acted on.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ename string\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe operation that is being attempted.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eThe server should set the \u003ccode\u003eRetry-After\u003c/code\u003e HTTP header and return\n\u003ccode\u003eretryAfterSeconds\u003c/code\u003e in the details field of the object. A value of \u003ccode\u003e0\u003c/code\u003e is the\ndefault.\u003c/li\u003e\n\u003cli\u003eHttp status code: \u003ccode\u003e504 StatusServerTimeout\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eMethodNotAllowed\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that the action the client attempted to perform on the resource\nwas not supported by the code.\u003c/li\u003e\n\u003cli\u003eFor instance, attempting to delete a resource that can only be created.\u003c/li\u003e\n\u003cli\u003eAPI calls that return MethodNotAllowed can never succeed.\u003c/li\u003e\n\u003cli\u003eHttp status code: \u003ccode\u003e405 StatusMethodNotAllowed\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eInternalError\u003c/code\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIndicates that an internal error occurred, it is unexpected and the outcome\nof the call is unknown.\u003c/li\u003e\n\u003cli\u003eDetails (optional):\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ecauses\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe original error.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHttp status code: \u003ccode\u003e500 StatusInternalServerError\u003c/code\u003e \u003ccode\u003ecode\u003c/code\u003e may contain the suggested HTTP return code for this status.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eEvents\u003c/h2\u003e\u003ca id=\"user-content-events\" class=\"anchor\" aria-label=\"Permalink: Events\" href=\"#events\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEvents are complementary to status information, since they can provide some\nhistorical information about status and occurrences in addition to current or\nprevious status. Generate events for situations users or administrators should\nbe alerted about.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eChoose a unique, specific, short, CamelCase reason for each event category. For\nexample, \u003ccode\u003eFreeDiskSpaceInvalid\u003c/code\u003e is a good event reason because it is likely to\nrefer to just one situation, but \u003ccode\u003eStarted\u003c/code\u003e is not a good reason because it\ndoesn't sufficiently indicate what started, even when combined with other event\nfields.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eError creating foo\u003c/code\u003e or \u003ccode\u003eError creating foo %s\u003c/code\u003e would be appropriate for an\nevent message, with the latter being preferable, since it is more informational.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAccumulate repeated events in the client, especially for frequent events, to\nreduce data volume, load on the system, and noise exposed to users.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNaming conventions\u003c/h2\u003e\u003ca id=\"user-content-naming-conventions\" class=\"anchor\" aria-label=\"Permalink: Naming conventions\" href=\"#naming-conventions\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eGo field names must be PascalCase. JSON field names must be camelCase. Other\nthan capitalization of the initial letter, the two should almost always match.\nNo underscores or dashes in either.\u003c/li\u003e\n\u003cli\u003eField and resource names should be declarative, not imperative (SomethingDoer,\nDoneBy, DoneAt).\u003c/li\u003e\n\u003cli\u003eUse \u003ccode\u003eNode\u003c/code\u003e where referring to\nthe node resource in the context of the cluster. Use \u003ccode\u003eHost\u003c/code\u003e where referring to\nproperties of the individual physical/virtual system, such as \u003ccode\u003ehostname\u003c/code\u003e,\n\u003ccode\u003ehostPath\u003c/code\u003e, \u003ccode\u003ehostNetwork\u003c/code\u003e, etc.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eFooController\u003c/code\u003e is a deprecated kind naming convention. Name the kind after\nthe thing being controlled instead (e.g., \u003ccode\u003eJob\u003c/code\u003e rather than \u003ccode\u003eJobController\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eThe name of a field that specifies the time at which \u003ccode\u003esomething\u003c/code\u003e occurs should\nbe called \u003ccode\u003esomethingTime\u003c/code\u003e. Do not use \u003ccode\u003estamp\u003c/code\u003e (e.g., \u003ccode\u003ecreationTimestamp\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eWe use the \u003ccode\u003efooSeconds\u003c/code\u003e convention for durations, as discussed in the \u003ca href=\"#units\"\u003eunits\nsubsection\u003c/a\u003e.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003efooPeriodSeconds\u003c/code\u003e is preferred for periodic intervals and other waiting\nperiods (e.g., over \u003ccode\u003efooIntervalSeconds\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003efooTimeoutSeconds\u003c/code\u003e is preferred for inactivity/unresponsiveness deadlines.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003efooDeadlineSeconds\u003c/code\u003e is preferred for activity completion deadlines.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eDo not use abbreviations in the API, except where they are extremely commonly\nused, such as \"id\", \"args\", or \"stdin\".\u003c/li\u003e\n\u003cli\u003eAcronyms should similarly only be used when extremely commonly known. All\nletters in the acronym should have the same case, using the appropriate case for\nthe situation. For example, at the beginning of a field name, the acronym should\nbe all lowercase, such as \"httpGet\". Where used as a constant, all letters\nshould be uppercase, such as \"TCP\" or \"UDP\".\u003c/li\u003e\n\u003cli\u003eThe name of a field referring to another resource of kind \u003ccode\u003eFoo\u003c/code\u003e by name should\nbe called \u003ccode\u003efooName\u003c/code\u003e. The name of a field referring to another resource of kind\n\u003ccode\u003eFoo\u003c/code\u003e by ObjectReference (or subset thereof) should be called \u003ccode\u003efooRef\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eMore generally, include the units and/or type in the field name if they could\nbe ambiguous and they are not specified by the value or value type.\u003c/li\u003e\n\u003cli\u003eThe name of a field expressing a boolean property called 'fooable' should be\ncalled \u003ccode\u003eFooable\u003c/code\u003e, not \u003ccode\u003eIsFooable\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNamespace Names\u003c/h3\u003e\u003ca id=\"user-content-namespace-names\" class=\"anchor\" aria-label=\"Permalink: Namespace Names\" href=\"#namespace-names\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe name of a namespace must be a\n\u003ca href=\"https://git.k8s.io/design-proposals-archive/architecture/identifiers.md\" rel=\"nofollow\"\u003eDNS_LABEL\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003ekube-\u003c/code\u003e prefix is reserved for Kubernetes system namespaces, e.g. \u003ccode\u003ekube-system\u003c/code\u003e and \u003ccode\u003ekube-public\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSee\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\" rel=\"nofollow\"\u003ethe namespace docs\u003c/a\u003e\nfor more information.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLabel, selector, and annotation conventions\u003c/h2\u003e\u003ca id=\"user-content-label-selector-and-annotation-conventions\" class=\"anchor\" aria-label=\"Permalink: Label, selector, and annotation conventions\" href=\"#label-selector-and-annotation-conventions\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eLabels are the domain of users. They are intended to facilitate organization and\nmanagement of API resources using attributes that are meaningful to users, as\nopposed to meaningful to the system. Think of them as user-created mp3 or email\ninbox labels, as opposed to the directory structure used by a program to store\nits data. The former enables the user to apply an arbitrary ontology, whereas\nthe latter is implementation-centric and inflexible. Users will use labels to\nselect resources to operate on, display label values in CLI/UI columns, etc.\nUsers should always retain full power and flexibility over the label schemas\nthey apply to labels in their namespaces.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHowever, we should support conveniences for common cases by default. For\nexample, what we now do in ReplicationController is automatically set the RC's\nselector and labels to the labels in the pod template by default, if they are\nnot already set. That ensures that the selector will match the template, and\nthat the RC can be managed using the same labels as the pods it creates. Note\nthat once we generalize selectors, it won't necessarily be possible to\nunambiguously generate labels that match an arbitrary selector.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf the user wants to apply additional labels to the pods that it doesn't select\nupon, such as to facilitate adoption of pods or in the expectation that some\nlabel values will change, they can set the selector to a subset of the pod\nlabels. Similarly, the RC's labels could be initialized to a subset of the pod\ntemplate's labels, or could include additional/different labels.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor disciplined users managing resources within their own namespaces, it's not\nthat hard to consistently apply schemas that ensure uniqueness. One just needs\nto ensure that at least one value of some label key in common differs compared\nto all other comparable resources. We could/should provide a verification tool\nto check that. However, development of conventions similar to the examples in\n\u003ca href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\" rel=\"nofollow\"\u003eLabels\u003c/a\u003e make uniqueness straightforward. Furthermore,\nrelatively narrowly used namespaces (e.g., per environment, per application) can\nbe used to reduce the set of resources that could potentially cause overlap.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn cases where users could be running misc. examples with inconsistent schemas,\nor where tooling or components need to programmatically generate new objects to\nbe selected, there needs to be a straightforward way to generate unique label\nsets. A simple way to ensure uniqueness of the set is to ensure uniqueness of a\nsingle label value, such as by using a resource name, uid, resource hash, or\ngeneration number.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eProblems with uids and hashes, however, include that they have no semantic\nmeaning to the user, are not memorable nor readily recognizable, and are not\npredictable. Lack of predictability obstructs use cases such as creation of a\nreplication controller from a pod, such as people want to do when exploring the\nsystem, bootstrapping a self-hosted cluster, or deletion and re-creation of a\nnew RC that adopts the pods of the previous one, such as to rename it.\nGeneration numbers are more predictable and much clearer, assuming there is a\nlogical sequence. Fortunately, for deployments that's the case. For jobs, use of\ncreation timestamps is common internally. Users should always be able to turn\noff auto-generation, in order to permit some of the scenarios described above.\nNote that auto-generated labels will also become one more field that needs to be\nstripped out when cloning a resource, within a namespace, in a new namespace, in\na new cluster, etc., and will need to be ignored around when updating a resource\nvia patch or read-modify-write sequence.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eInclusion of a system prefix in a label key is fairly hostile to UX. A prefix is\nonly necessary in the case that the user cannot choose the label key, in order\nto avoid collisions with user-defined labels. However, I firmly believe that the\nuser should always be allowed to select the label keys to use on their\nresources, so it should always be possible to override default label keys.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTherefore, resources supporting auto-generation of unique labels should have a\n\u003ccode\u003euniqueLabelKey\u003c/code\u003e field, so that the user could specify the key if they wanted\nto, but if unspecified, it could be set by default, such as to the resource\ntype, like job, deployment, or replicationController. The value would need to be\nat least spatially unique, and perhaps temporally unique in the case of job.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAnnotations have very different intended usage from labels. They are\nprimarily generated and consumed by tooling and system extensions, or are used\nby end-users to engage non-standard behavior of components. For example, an\nannotation might be used to indicate that an instance of a resource expects\nadditional handling by non-kubernetes controllers. Annotations may carry\narbitrary payloads, including JSON documents. Like labels, annotation keys can\nbe prefixed with a governing domain (e.g. \u003ccode\u003eexample.com/key-name\u003c/code\u003e). Unprefixed\nkeys (e.g. \u003ccode\u003ekey-name\u003c/code\u003e) are reserved for end-users. Third-party components must\nuse prefixed keys. Key prefixes under the \"kubernetes.io\" and \"k8s.io\" domains\nare reserved for use by the kubernetes project and must not be used by\nthird-parties.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn early versions of Kubernetes, some in-development features represented new\nAPI fields as annotations, generally with the form \u003ccode\u003esomething.alpha.kubernetes.io/name\u003c/code\u003e or\n\u003ccode\u003esomething.beta.kubernetes.io/name\u003c/code\u003e (depending on our confidence in it). This\npattern is deprecated. Some such annotations may still exist, but no new\nannotations may be defined. New API fields are now developed as regular fields.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOther advice regarding use of labels, annotations, taints, and other generic map keys by\nKubernetes components and tools:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eKey names should be all lowercase, with words separated by dashes instead of camelCase\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor instance, prefer \u003ccode\u003efoo.kubernetes.io/foo-bar\u003c/code\u003e over \u003ccode\u003efoo.kubernetes.io/fooBar\u003c/code\u003e, prefer\n\u003ccode\u003edesired-replicas\u003c/code\u003e over \u003ccode\u003eDesiredReplicas\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eUnprefixed keys are reserved for end-users. All other labels and annotations must be prefixed.\u003c/li\u003e\n\u003cli\u003eKey prefixes under \"kubernetes.io\" and \"k8s.io\" are reserved for the Kubernetes\nproject.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSuch keys are effectively part of the kubernetes API and may be subject\nto deprecation and compatibility policies.\u003c/li\u003e\n\u003cli\u003e\"kubernetes.io\" is the preferred form for labels and annotations, \"k8s.io\" should not be used\nfor new map keys.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eKey names, including prefixes, should be precise enough that a user could\nplausibly understand where it came from and what it is for.\u003c/li\u003e\n\u003cli\u003eKey prefixes should carry as much context as possible.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor instance, prefer \u003ccode\u003esubsystem.kubernetes.io/parameter\u003c/code\u003e over \u003ccode\u003ekubernetes.io/subsystem-parameter\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eUse annotations to store API extensions that the controller responsible for\nthe resource doesn't need to know about, experimental fields that aren't\nintended to be generally used API fields, etc. Beware that annotations aren't\nautomatically handled by the API conversion machinery.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWebSockets and SPDY\u003c/h2\u003e\u003ca id=\"user-content-websockets-and-spdy\" class=\"anchor\" aria-label=\"Permalink: WebSockets and SPDY\" href=\"#websockets-and-spdy\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSome of the API operations exposed by Kubernetes involve transfer of binary\nstreams between the client and a container, including attach, exec, portforward,\nand logging. The API therefore exposes certain operations over upgradeable HTTP\nconnections (\u003ca href=\"https://tools.ietf.org/html/rfc2817\" rel=\"nofollow\"\u003edescribed in RFC 2817\u003c/a\u003e) via\nthe WebSocket and SPDY protocols. These actions are exposed as subresources with\ntheir associated verbs (exec, log, attach, and portforward) and are requested\nvia a GET (to support JavaScript in a browser) and POST (semantically accurate).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere are two primary protocols in use today:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eStreamed channels\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen dealing with multiple independent binary streams of data such as the\nremote execution of a shell command (writing to STDIN, reading from STDOUT and\nSTDERR) or forwarding multiple ports the streams can be multiplexed onto a\nsingle TCP connection. Kubernetes supports a SPDY based framing protocol that\nleverages SPDY channels and a WebSocket framing protocol that multiplexes\nmultiple channels onto the same stream by prefixing each binary chunk with a\nbyte indicating its channel. The WebSocket protocol supports an optional\nsubprotocol that handles base64-encoded bytes from the client and returns\nbase64-encoded bytes from the server and character based channel prefixes ('0',\n'1', '2') for ease of use from JavaScript in a browser.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eStreaming response\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe default log output for a channel of streaming data is an HTTP Chunked\nTransfer-Encoding, which can return an arbitrary stream of binary data from the\nserver. Browser-based JavaScript is limited in its ability to access the raw\ndata from a chunked response, especially when very large amounts of logs are\nreturned, and in future API calls it may be desirable to transfer large files.\nThe streaming API endpoints support an optional WebSocket upgrade that provides\na unidirectional channel from the server to the client and chunks data as binary\nWebSocket frames. An optional WebSocket subprotocol is exposed that base64\nencodes the stream before returning it to the client.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eClients should use the SPDY protocols if their clients have native support, or\nWebSockets as a fallback. Note that WebSockets is susceptible to Head-of-Line\nblocking and so clients must read and process each message sequentially. In\nthe future, an HTTP/2 implementation will be exposed that deprecates SPDY.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eValidation\u003c/h2\u003e\u003ca id=\"user-content-validation\" class=\"anchor\" aria-label=\"Permalink: Validation\" href=\"#validation\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAPI objects are validated upon receipt by the apiserver. Validation errors are\nflagged and returned to the caller in a \u003ccode\u003eFailure\u003c/code\u003e status with \u003ccode\u003ereason\u003c/code\u003e set to\n\u003ccode\u003eInvalid\u003c/code\u003e. In order to facilitate consistent error messages, we ask that\nvalidation logic adheres to the following guidelines whenever possible (though\nexceptional cases will exist).\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eBe as precise as possible.\u003c/li\u003e\n\u003cli\u003eTelling users what they CAN do is more useful than telling them what they\nCANNOT do.\u003c/li\u003e\n\u003cli\u003eWhen asserting a requirement in the positive, use \"must\". Examples: \"must be\ngreater than 0\", \"must match regex '[a-z]+'\". Words like \"should\" imply that\nthe assertion is optional, and must be avoided.\u003c/li\u003e\n\u003cli\u003eWhen asserting a formatting requirement in the negative, use \"must not\".\nExample: \"must not contain '..'\". Words like \"should not\" imply that the\nassertion is optional, and must be avoided.\u003c/li\u003e\n\u003cli\u003eWhen asserting a behavioral requirement in the negative, use \"may not\".\nExamples: \"may not be specified when otherField is empty\", \"only \u003ccode\u003ename\u003c/code\u003e may be\nspecified\".\u003c/li\u003e\n\u003cli\u003eWhen referencing a literal string value, indicate the literal in\nsingle-quotes. Example: \"must not contain '..'\".\u003c/li\u003e\n\u003cli\u003eWhen referencing another field name, indicate the name in back-quotes.\nExample: \"must be greater than `request`\".\u003c/li\u003e\n\u003cli\u003eWhen specifying inequalities, use words rather than symbols. Examples: \"must\nbe less than 256\", \"must be greater than or equal to 0\". Do not use words\nlike \"larger than\", \"bigger than\", \"more than\", \"higher than\", etc.\u003c/li\u003e\n\u003cli\u003eWhen specifying numeric ranges, use inclusive ranges when possible.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAutomatic Resource Allocation And Deallocation\u003c/h2\u003e\u003ca id=\"user-content-automatic-resource-allocation-and-deallocation\" class=\"anchor\" aria-label=\"Permalink: Automatic Resource Allocation And Deallocation\" href=\"#automatic-resource-allocation-and-deallocation\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAPI objects often are \u003ca href=\"#Unions\"\u003eunion\u003c/a\u003e object containing the following:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eOne or more fields identifying the \u003ccode\u003eType\u003c/code\u003e specific to API object (aka the \u003ccode\u003ediscriminator\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eA set of N fields, only one of which should be set at any given time - effectively a union.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eControllers operating on the API type often allocate resources based on\nthe \u003ccode\u003eType\u003c/code\u003e and/or some additional data provided by user. A canonical example\nof this is the \u003ccode\u003eService\u003c/code\u003e API object where resources such as IPs and network ports\nwill be set in the API object based on \u003ccode\u003eType\u003c/code\u003e. When the user does not specify\nresources, they will be allocated, and when the user specifies exact value, they will\nbe reserved or rejected.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen the user chooses to change the \u003ccode\u003ediscriminator\u003c/code\u003e value (e.g., from \u003ccode\u003eType X\u003c/code\u003e to \u003ccode\u003eType Y\u003c/code\u003e) without\nchanging any other fields then the system should clear the fields that were used to represent \u003ccode\u003eType X\u003c/code\u003e\nin the union along with releasing resources that were attached to \u003ccode\u003eType X\u003c/code\u003e. This should automatically\nhappen irrespective of how these values and resources were allocated (i.e., reserved by the user or\nautomatically allocated by the system. A concrete example of this is again \u003ccode\u003eService\u003c/code\u003e API. The system\nallocates resources such as \u003ccode\u003eNodePorts\u003c/code\u003e and \u003ccode\u003eClusterIPs\u003c/code\u003e and automatically fill in the fields that\nrepresent them in case of the service is of type \u003ccode\u003eNodePort\u003c/code\u003e or \u003ccode\u003eClusterIP\u003c/code\u003e (\u003ccode\u003ediscriminator\u003c/code\u003e values).\nThese resources and the fields representing them are automatically cleared when the users changes\nservice type to \u003ccode\u003eExternalName\u003c/code\u003e where these resources and field values no longer apply.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRepresenting Allocated Values\u003c/h2\u003e\u003ca id=\"user-content-representing-allocated-values\" class=\"anchor\" aria-label=\"Permalink: Representing Allocated Values\" href=\"#representing-allocated-values\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMany API types include values that are allocated on behalf of the user from\nsome larger space (e.g. IP addresses from a range, or storage bucket names).\nThese allocations are usually driven by controllers asynchronously to the\nuser's API operations. Sometimes the user can request a specific value and a\ncontroller must confirm or reject that request. There are many examples of\nthis in Kubernetes, and there a handful of patterns used to represent it.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe common theme among all of these is that the system should not trust users\nwith such fields, and must verify or otherwise confirm such requests before\nusing them.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSome examples:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eService \u003ccode\u003eclusterIP\u003c/code\u003e: Users may request a specific IP in \u003ccode\u003espec\u003c/code\u003e or will be\nallocated one (in the same \u003ccode\u003espec\u003c/code\u003e field). If a specific IP is requested, the\napiserver will either confirm that IP is available or, failing that, will\nreject the API operation synchronously (rare). Consumers read the result\nfrom \u003ccode\u003espec\u003c/code\u003e. This is safe because the value is either valid or it is never\nstored.\u003c/li\u003e\n\u003cli\u003eService \u003ccode\u003eloadBalancerIP\u003c/code\u003e: Users may request a specific IP in \u003ccode\u003espec\u003c/code\u003e or will\nbe allocated one which is reported in \u003ccode\u003estatus\u003c/code\u003e. If a specific IP is\nrequested, the LB controller will either ensure that IP is available or\nreport failure asynchronously. Consumers read the result from \u003ccode\u003estatus\u003c/code\u003e.\nThis is safe because most users do not have acces to write to \u003ccode\u003estatus\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003ePersistentVolumeClaims: Users may request a specific PersistentVolume in\n\u003ccode\u003espec\u003c/code\u003e or will be allocated one (in the same \u003ccode\u003espec\u003c/code\u003e field). If a specific PV\nis requested, the volume controller will either ensure that the volume is\navailable or report failure asynchronously. Consumers read the result by\nexamining both the PVC and the PV. This is more complicated than the others\nbecause the \u003ccode\u003espec\u003c/code\u003e value is stored before being confirmed, which could\n(hypothetically, thanks to extra checking) lead to a user accessing someone\nelse's PV.\u003c/li\u003e\n\u003cli\u003eVolumeSnapshots: Users may request a particular source to be snaphotted in\n\u003ccode\u003espec\u003c/code\u003e. The details of the resulting snapshot is reflected in \u003ccode\u003estatus\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eA counter-example:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eService \u003ccode\u003eexternalIPs\u003c/code\u003e: Users must specify one or more specific IPs in \u003ccode\u003espec\u003c/code\u003e.\nThe system cannot easily verify those IPs (by their definition, they are\nexternal). Consumers read the result from \u003ccode\u003espec\u003c/code\u003e. This is UNSAFE and has\ncaused problems with untrusted users.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eIn the past, API conventions dictated that \u003ccode\u003estatus\u003c/code\u003e fields always come from\nobservation, which made some of these cases more complicated than necessary.\nThe conventions have been updated to allow \u003ccode\u003estatus\u003c/code\u003e to hold such allocated\nvalues. This is not a one-size-fits-all solution, though.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhen to use a \u003ccode\u003espec\u003c/code\u003e field\u003c/h3\u003e\u003ca id=\"user-content-when-to-use-a-spec-field\" class=\"anchor\" aria-label=\"Permalink: When to use a spec field\" href=\"#when-to-use-a-spec-field\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNew APIs should almost never do this. Instead, they should use \u003ccode\u003estatus\u003c/code\u003e.\nPersistentVolumes might have been simpler if we had done this.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhen to use a \u003ccode\u003estatus\u003c/code\u003e field\u003c/h3\u003e\u003ca id=\"user-content-when-to-use-a-status-field\" class=\"anchor\" aria-label=\"Permalink: When to use a status field\" href=\"#when-to-use-a-status-field\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStoring such values in \u003ccode\u003estatus\u003c/code\u003e is the easiest and most straight-forward\npattern. This is appropriate when:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ethe allocated value is highly coupled to the rest of the object (e.g. pod\nresource allocations)\u003c/li\u003e\n\u003cli\u003ethe allocated value is always or almost always needed (i.e. most instances of\nthis type will have a value)\u003c/li\u003e\n\u003cli\u003ethe schema and controller are known a priori (i.e. it's not an extension)\u003c/li\u003e\n\u003cli\u003eit is \"safe\" to allow the controller(s) to write to \u003ccode\u003estatus\u003c/code\u003e (i.e.\nthere's low risk of them causing problems via other \u003ccode\u003estatus\u003c/code\u003e fields).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eConsumers of such values can look at the \u003ccode\u003estatus\u003c/code\u003e field for the \"final\" value\nor an error or condition indicating why the allocation could not be performed.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSequencing operations\u003c/h4\u003e\u003ca id=\"user-content-sequencing-operations\" class=\"anchor\" aria-label=\"Permalink: Sequencing operations\" href=\"#sequencing-operations\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSince almost everything is happening asynchronously to almost everything else,\ncontroller implementations should take care around the ordering of operations.\nFor example, whether the controller updates a \u003ccode\u003estatus\u003c/code\u003e field before or after it\nactuates a change depends on what guarantees need to be made to observers of\nthe system. In some cases, writing to a \u003ccode\u003estatus\u003c/code\u003e field represents an\nacknowledgement or acceptance of a \u003ccode\u003espec\u003c/code\u003e value, and it is OK to write it before\nactuation. However, if it would be problematic for a client to observe the\n\u003ccode\u003estatus\u003c/code\u003e value before it is actuated then the controller must actuate first and\nupdate \u003ccode\u003estatus\u003c/code\u003e afterward. In some rarer cases, controllers will need to\nacknowledge, then actuate, then update to a \"final\" value.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eControllers must take care to consider how a \u003ccode\u003estatus\u003c/code\u003e field will be handled in\nthe case of interrupted control loops (e.g. controller crash and restart), and\nmust act idempotently and consistently. This is particularly important when\nusing an informer-fed cache, which might not be updated with recent writes.\nUsing a resourceVersion precondition to detect the \"conflict\" is the common\npattern in this case. See \u003ca href=\"http://issue.k8s.io/105199\" rel=\"nofollow\"\u003ethis issue\u003c/a\u003e for an\nexample.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhen to use a different type\u003c/h3\u003e\u003ca id=\"user-content-when-to-use-a-different-type\" class=\"anchor\" aria-label=\"Permalink: When to use a different type\" href=\"#when-to-use-a-different-type\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStoring allocated values in a different type is more complicated but also more\nflexible. This is most appropriate when:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ethe allocated value is optional (i.e. many instances of this type will not\nhave a value at all)\u003c/li\u003e\n\u003cli\u003ethe schema and controller are not known a priori (i.e. it's an extension)\u003c/li\u003e\n\u003cli\u003ethe schema is sufficiently complicated (i.e. it doesn't make sense to burden\nthe main type with it)\u003c/li\u003e\n\u003cli\u003eaccess control for this type demands finer granularity than \"all of status\"\u003c/li\u003e\n\u003cli\u003ethe lifecycle of the allocated value is different than the lifecycle of the\nallocation holder\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eServices and Endpoints could be considered a form of this pattern, as could\nPersistentVolumes and PersistentVolumeClaims.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen using this pattern, you must account for lifecycle of the allocated\nobjects (who cleans them up and when) as well as the \"linkage\" between them and\nthe main type (often using the same name, an object-ref field, or a selector).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere will always be some cases which could follow either path, and these will\nneed human evaluation to decide. For example, Service \u003ccode\u003eclusterIP\u003c/code\u003e is highly\ncoupled to the rest of Service and most instances use it. But it also is\nstrictly optional and has an increasingly complicated schema of related fields.\nAn argument could be made for either path.\u003c/p\u003e\n\u003c/article\u003e","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":8,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"API Conventions","kind":"section_1","ident_start":0,"ident_end":15,"extent_start":0,"extent_end":32,"fully_qualified_name":"API Conventions","ident_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":0,"utf16_col":15}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":2,"utf16_col":0}}},{"name":"Types (Kinds)","kind":"section_2","ident_start":6564,"ident_end":6577,"extent_start":6561,"extent_end":35451,"fully_qualified_name":"Types (Kinds)","ident_utf16":{"start":{"line_number":126,"utf16_col":3},"end":{"line_number":126,"utf16_col":16}},"extent_utf16":{"start":{"line_number":126,"utf16_col":0},"end":{"line_number":660,"utf16_col":0}}},{"name":"Resources","kind":"section_3","ident_start":10965,"ident_end":10974,"extent_start":10961,"extent_end":11423,"fully_qualified_name":"Resources","ident_utf16":{"start":{"line_number":213,"utf16_col":4},"end":{"line_number":213,"utf16_col":13}},"extent_utf16":{"start":{"line_number":213,"utf16_col":0},"end":{"line_number":225,"utf16_col":0}}},{"name":"Objects","kind":"section_3","ident_start":11427,"ident_end":11434,"extent_start":11423,"extent_end":34684,"fully_qualified_name":"Objects","ident_utf16":{"start":{"line_number":225,"utf16_col":4},"end":{"line_number":225,"utf16_col":11}},"extent_utf16":{"start":{"line_number":225,"utf16_col":0},"end":{"line_number":643,"utf16_col":0}}},{"name":"Metadata","kind":"section_4","ident_start":11441,"ident_end":11449,"extent_start":11436,"extent_end":14563,"fully_qualified_name":"Metadata","ident_utf16":{"start":{"line_number":227,"utf16_col":5},"end":{"line_number":227,"utf16_col":13}},"extent_utf16":{"start":{"line_number":227,"utf16_col":0},"end":{"line_number":278,"utf16_col":0}}},{"name":"Spec and Status","kind":"section_4","ident_start":14568,"ident_end":14583,"extent_start":14563,"extent_end":29273,"fully_qualified_name":"Spec and Status","ident_utf16":{"start":{"line_number":278,"utf16_col":5},"end":{"line_number":278,"utf16_col":20}},"extent_utf16":{"start":{"line_number":278,"utf16_col":0},"end":{"line_number":533,"utf16_col":0}}},{"name":"Typical status properties","kind":"section_5","ident_start":18816,"ident_end":18841,"extent_start":18810,"extent_end":29273,"fully_qualified_name":"Typical status properties","ident_utf16":{"start":{"line_number":350,"utf16_col":6},"end":{"line_number":350,"utf16_col":31}},"extent_utf16":{"start":{"line_number":350,"utf16_col":0},"end":{"line_number":533,"utf16_col":0}}},{"name":"References to related objects","kind":"section_4","ident_start":29278,"ident_end":29307,"extent_start":29273,"extent_end":30163,"fully_qualified_name":"References to related objects","ident_utf16":{"start":{"line_number":533,"utf16_col":5},"end":{"line_number":533,"utf16_col":34}},"extent_utf16":{"start":{"line_number":533,"utf16_col":0},"end":{"line_number":550,"utf16_col":0}}},{"name":"Lists of named subobjects preferred over maps","kind":"section_4","ident_start":30168,"ident_end":30213,"extent_start":30163,"extent_end":30979,"fully_qualified_name":"Lists of named subobjects preferred over maps","ident_utf16":{"start":{"line_number":550,"utf16_col":5},"end":{"line_number":550,"utf16_col":50}},"extent_utf16":{"start":{"line_number":550,"utf16_col":0},"end":{"line_number":579,"utf16_col":0}}},{"name":"Primitive types","kind":"section_4","ident_start":30984,"ident_end":30999,"extent_start":30979,"extent_end":32714,"fully_qualified_name":"Primitive types","ident_utf16":{"start":{"line_number":579,"utf16_col":5},"end":{"line_number":579,"utf16_col":20}},"extent_utf16":{"start":{"line_number":579,"utf16_col":0},"end":{"line_number":608,"utf16_col":0}}},{"name":"Constants","kind":"section_4","ident_start":32719,"ident_end":32728,"extent_start":32714,"extent_end":34074,"fully_qualified_name":"Constants","ident_utf16":{"start":{"line_number":608,"utf16_col":5},"end":{"line_number":608,"utf16_col":14}},"extent_utf16":{"start":{"line_number":608,"utf16_col":0},"end":{"line_number":630,"utf16_col":0}}},{"name":"Unions","kind":"section_4","ident_start":34079,"ident_end":34085,"extent_start":34074,"extent_end":34684,"fully_qualified_name":"Unions","ident_utf16":{"start":{"line_number":630,"utf16_col":5},"end":{"line_number":630,"utf16_col":11}},"extent_utf16":{"start":{"line_number":630,"utf16_col":0},"end":{"line_number":643,"utf16_col":0}}},{"name":"Lists and Simple kinds","kind":"section_3","ident_start":34688,"ident_end":34710,"extent_start":34684,"extent_end":35451,"fully_qualified_name":"Lists and Simple kinds","ident_utf16":{"start":{"line_number":643,"utf16_col":4},"end":{"line_number":643,"utf16_col":26}},"extent_utf16":{"start":{"line_number":643,"utf16_col":0},"end":{"line_number":660,"utf16_col":0}}},{"name":"Differing Representations","kind":"section_2","ident_start":35454,"ident_end":35479,"extent_start":35451,"extent_end":36516,"fully_qualified_name":"Differing Representations","ident_utf16":{"start":{"line_number":660,"utf16_col":3},"end":{"line_number":660,"utf16_col":28}},"extent_utf16":{"start":{"line_number":660,"utf16_col":0},"end":{"line_number":682,"utf16_col":0}}},{"name":"Verbs on Resources","kind":"section_2","ident_start":36519,"ident_end":36537,"extent_start":36516,"extent_end":39417,"fully_qualified_name":"Verbs on Resources","ident_utf16":{"start":{"line_number":682,"utf16_col":3},"end":{"line_number":682,"utf16_col":21}},"extent_utf16":{"start":{"line_number":682,"utf16_col":0},"end":{"line_number":732,"utf16_col":0}}},{"name":"PATCH operations","kind":"section_3","ident_start":38305,"ident_end":38321,"extent_start":38301,"extent_end":39417,"fully_qualified_name":"PATCH operations","ident_utf16":{"start":{"line_number":712,"utf16_col":4},"end":{"line_number":712,"utf16_col":20}},"extent_utf16":{"start":{"line_number":712,"utf16_col":0},"end":{"line_number":732,"utf16_col":0}}},{"name":"Short-names and Categories","kind":"section_2","ident_start":39420,"ident_end":39446,"extent_start":39417,"extent_end":43033,"fully_qualified_name":"Short-names and Categories","ident_utf16":{"start":{"line_number":732,"utf16_col":3},"end":{"line_number":732,"utf16_col":29}},"extent_utf16":{"start":{"line_number":732,"utf16_col":0},"end":{"line_number":800,"utf16_col":0}}},{"name":"Short-names","kind":"section_3","ident_start":39944,"ident_end":39955,"extent_start":39940,"extent_end":41148,"fully_qualified_name":"Short-names","ident_utf16":{"start":{"line_number":742,"utf16_col":4},"end":{"line_number":742,"utf16_col":15}},"extent_utf16":{"start":{"line_number":742,"utf16_col":0},"end":{"line_number":765,"utf16_col":0}}},{"name":"Categories","kind":"section_3","ident_start":41152,"ident_end":41162,"extent_start":41148,"extent_end":43033,"fully_qualified_name":"Categories","ident_utf16":{"start":{"line_number":765,"utf16_col":4},"end":{"line_number":765,"utf16_col":14}},"extent_utf16":{"start":{"line_number":765,"utf16_col":0},"end":{"line_number":800,"utf16_col":0}}},{"name":"Idempotency","kind":"section_2","ident_start":43036,"ident_end":43047,"extent_start":43033,"extent_end":44209,"fully_qualified_name":"Idempotency","ident_utf16":{"start":{"line_number":800,"utf16_col":3},"end":{"line_number":800,"utf16_col":14}},"extent_utf16":{"start":{"line_number":800,"utf16_col":0},"end":{"line_number":820,"utf16_col":0}}},{"name":"Optional vs. Required","kind":"section_2","ident_start":44212,"ident_end":44233,"extent_start":44209,"extent_end":46413,"fully_qualified_name":"Optional vs. Required","ident_utf16":{"start":{"line_number":820,"utf16_col":3},"end":{"line_number":820,"utf16_col":24}},"extent_utf16":{"start":{"line_number":820,"utf16_col":0},"end":{"line_number":869,"utf16_col":0}}},{"name":"Defaulting","kind":"section_2","ident_start":46416,"ident_end":46426,"extent_start":46413,"extent_end":56182,"fully_qualified_name":"Defaulting","ident_utf16":{"start":{"line_number":869,"utf16_col":3},"end":{"line_number":869,"utf16_col":13}},"extent_utf16":{"start":{"line_number":869,"utf16_col":0},"end":{"line_number":1047,"utf16_col":0}}},{"name":"Static Defaults","kind":"section_3","ident_start":47530,"ident_end":47545,"extent_start":47526,"extent_end":50174,"fully_qualified_name":"Static Defaults","ident_utf16":{"start":{"line_number":893,"utf16_col":4},"end":{"line_number":893,"utf16_col":19}},"extent_utf16":{"start":{"line_number":893,"utf16_col":0},"end":{"line_number":938,"utf16_col":0}}},{"name":"Admission Controlled Defaults","kind":"section_3","ident_start":50178,"ident_end":50207,"extent_start":50174,"extent_end":51431,"fully_qualified_name":"Admission Controlled Defaults","ident_utf16":{"start":{"line_number":938,"utf16_col":4},"end":{"line_number":938,"utf16_col":33}},"extent_utf16":{"start":{"line_number":938,"utf16_col":0},"end":{"line_number":962,"utf16_col":0}}},{"name":"Controller-Assigned Defaults (aka Late Initialization)","kind":"section_3","ident_start":51435,"ident_end":51489,"extent_start":51431,"extent_end":52377,"fully_qualified_name":"Controller-Assigned Defaults (aka Late Initialization)","ident_utf16":{"start":{"line_number":962,"utf16_col":4},"end":{"line_number":962,"utf16_col":58}},"extent_utf16":{"start":{"line_number":962,"utf16_col":0},"end":{"line_number":980,"utf16_col":0}}},{"name":"What May Be Defaulted","kind":"section_3","ident_start":52381,"ident_end":52402,"extent_start":52377,"extent_end":53085,"fully_qualified_name":"What May Be Defaulted","ident_utf16":{"start":{"line_number":980,"utf16_col":4},"end":{"line_number":980,"utf16_col":25}},"extent_utf16":{"start":{"line_number":980,"utf16_col":0},"end":{"line_number":997,"utf16_col":0}}},{"name":"Considerations For PUT Operations","kind":"section_3","ident_start":53089,"ident_end":53122,"extent_start":53085,"extent_end":56182,"fully_qualified_name":"Considerations For PUT Operations","ident_utf16":{"start":{"line_number":997,"utf16_col":4},"end":{"line_number":997,"utf16_col":37}},"extent_utf16":{"start":{"line_number":997,"utf16_col":0},"end":{"line_number":1047,"utf16_col":0}}},{"name":"Concurrency Control and Consistency","kind":"section_2","ident_start":56185,"ident_end":56220,"extent_start":56182,"extent_end":59516,"fully_qualified_name":"Concurrency Control and Consistency","ident_utf16":{"start":{"line_number":1047,"utf16_col":3},"end":{"line_number":1047,"utf16_col":38}},"extent_utf16":{"start":{"line_number":1047,"utf16_col":0},"end":{"line_number":1110,"utf16_col":0}}},{"name":"Serialization Format","kind":"section_2","ident_start":59519,"ident_end":59539,"extent_start":59516,"extent_end":59966,"fully_qualified_name":"Serialization Format","ident_utf16":{"start":{"line_number":1110,"utf16_col":3},"end":{"line_number":1110,"utf16_col":23}},"extent_utf16":{"start":{"line_number":1110,"utf16_col":0},"end":{"line_number":1122,"utf16_col":0}}},{"name":"Units","kind":"section_2","ident_start":59969,"ident_end":59974,"extent_start":59966,"extent_end":60453,"fully_qualified_name":"Units","ident_utf16":{"start":{"line_number":1122,"utf16_col":3},"end":{"line_number":1122,"utf16_col":8}},"extent_utf16":{"start":{"line_number":1122,"utf16_col":0},"end":{"line_number":1133,"utf16_col":0}}},{"name":"Selecting Fields","kind":"section_2","ident_start":60456,"ident_end":60472,"extent_start":60453,"extent_end":60944,"fully_qualified_name":"Selecting Fields","ident_utf16":{"start":{"line_number":1133,"utf16_col":3},"end":{"line_number":1133,"utf16_col":19}},"extent_utf16":{"start":{"line_number":1133,"utf16_col":0},"end":{"line_number":1146,"utf16_col":0}}},{"name":"Object references","kind":"section_2","ident_start":60947,"ident_end":60964,"extent_start":60944,"extent_end":73398,"fully_qualified_name":"Object references","ident_utf16":{"start":{"line_number":1146,"utf16_col":3},"end":{"line_number":1146,"utf16_col":20}},"extent_utf16":{"start":{"line_number":1146,"utf16_col":0},"end":{"line_number":1383,"utf16_col":0}}},{"name":"Naming of the reference field","kind":"section_3","ident_start":62766,"ident_end":62795,"extent_start":62762,"extent_end":63496,"fully_qualified_name":"Naming of the reference field","ident_utf16":{"start":{"line_number":1169,"utf16_col":4},"end":{"line_number":1169,"utf16_col":33}},"extent_utf16":{"start":{"line_number":1169,"utf16_col":0},"end":{"line_number":1183,"utf16_col":0}}},{"name":"Referencing resources with multiple versions","kind":"section_3","ident_start":63500,"ident_end":63544,"extent_start":63496,"extent_end":63792,"fully_qualified_name":"Referencing resources with multiple versions","ident_utf16":{"start":{"line_number":1183,"utf16_col":4},"end":{"line_number":1183,"utf16_col":48}},"extent_utf16":{"start":{"line_number":1183,"utf16_col":0},"end":{"line_number":1190,"utf16_col":0}}},{"name":"Handling of resources that do not exist","kind":"section_3","ident_start":63796,"ident_end":63835,"extent_start":63792,"extent_end":64241,"fully_qualified_name":"Handling of resources that do not exist","ident_utf16":{"start":{"line_number":1190,"utf16_col":4},"end":{"line_number":1190,"utf16_col":43}},"extent_utf16":{"start":{"line_number":1190,"utf16_col":0},"end":{"line_number":1201,"utf16_col":0}}},{"name":"Validation of fields","kind":"section_3","ident_start":64245,"ident_end":64265,"extent_start":64241,"extent_end":64873,"fully_qualified_name":"Validation of fields","ident_utf16":{"start":{"line_number":1201,"utf16_col":4},"end":{"line_number":1201,"utf16_col":24}},"extent_utf16":{"start":{"line_number":1201,"utf16_col":0},"end":{"line_number":1213,"utf16_col":0}}},{"name":"Do not modify the referred object","kind":"section_3","ident_start":64877,"ident_end":64910,"extent_start":64873,"extent_end":65214,"fully_qualified_name":"Do not modify the referred object","ident_utf16":{"start":{"line_number":1213,"utf16_col":4},"end":{"line_number":1213,"utf16_col":37}},"extent_utf16":{"start":{"line_number":1213,"utf16_col":0},"end":{"line_number":1219,"utf16_col":0}}},{"name":"Minimize copying or printing values to the referrer object","kind":"section_3","ident_start":65218,"ident_end":65276,"extent_start":65214,"extent_end":66129,"fully_qualified_name":"Minimize copying or printing values to the referrer object","ident_utf16":{"start":{"line_number":1219,"utf16_col":4},"end":{"line_number":1219,"utf16_col":62}},"extent_utf16":{"start":{"line_number":1219,"utf16_col":0},"end":{"line_number":1235,"utf16_col":0}}},{"name":"Object References Examples","kind":"section_3","ident_start":66133,"ident_end":66159,"extent_start":66129,"extent_end":73398,"fully_qualified_name":"Object References Examples","ident_utf16":{"start":{"line_number":1235,"utf16_col":4},"end":{"line_number":1235,"utf16_col":30}},"extent_utf16":{"start":{"line_number":1235,"utf16_col":0},"end":{"line_number":1383,"utf16_col":0}}},{"name":"Single resource reference","kind":"section_4","ident_start":66552,"ident_end":66577,"extent_start":66547,"extent_end":67591,"fully_qualified_name":"Single resource reference","ident_utf16":{"start":{"line_number":1245,"utf16_col":5},"end":{"line_number":1245,"utf16_col":30}},"extent_utf16":{"start":{"line_number":1245,"utf16_col":0},"end":{"line_number":1266,"utf16_col":0}}},{"name":"Controller behavior","kind":"section_5","ident_start":67378,"ident_end":67397,"extent_start":67372,"extent_end":67591,"fully_qualified_name":"Controller behavior","ident_utf16":{"start":{"line_number":1262,"utf16_col":6},"end":{"line_number":1262,"utf16_col":25}},"extent_utf16":{"start":{"line_number":1262,"utf16_col":0},"end":{"line_number":1266,"utf16_col":0}}},{"name":"Multiple resource reference","kind":"section_4","ident_start":67596,"ident_end":67623,"extent_start":67591,"extent_end":71343,"fully_qualified_name":"Multiple resource reference","ident_utf16":{"start":{"line_number":1266,"utf16_col":5},"end":{"line_number":1266,"utf16_col":32}},"extent_utf16":{"start":{"line_number":1266,"utf16_col":0},"end":{"line_number":1339,"utf16_col":0}}},{"name":"Kind vs. Resource","kind":"section_5","ident_start":68487,"ident_end":68504,"extent_start":68481,"extent_end":70915,"fully_qualified_name":"Kind vs. Resource","ident_utf16":{"start":{"line_number":1283,"utf16_col":6},"end":{"line_number":1283,"utf16_col":23}},"extent_utf16":{"start":{"line_number":1283,"utf16_col":0},"end":{"line_number":1332,"utf16_col":0}}},{"name":"Controller behavior","kind":"section_5","ident_start":70921,"ident_end":70940,"extent_start":70915,"extent_end":71343,"fully_qualified_name":"Controller behavior","ident_utf16":{"start":{"line_number":1332,"utf16_col":6},"end":{"line_number":1332,"utf16_col":25}},"extent_utf16":{"start":{"line_number":1332,"utf16_col":0},"end":{"line_number":1339,"utf16_col":0}}},{"name":"Generic object reference","kind":"section_4","ident_start":71348,"ident_end":71372,"extent_start":71343,"extent_end":72329,"fully_qualified_name":"Generic object reference","ident_utf16":{"start":{"line_number":1339,"utf16_col":5},"end":{"line_number":1339,"utf16_col":29}},"extent_utf16":{"start":{"line_number":1339,"utf16_col":0},"end":{"line_number":1358,"utf16_col":0}}},{"name":"Controller behavior","kind":"section_5","ident_start":72100,"ident_end":72119,"extent_start":72094,"extent_end":72329,"fully_qualified_name":"Controller behavior","ident_utf16":{"start":{"line_number":1354,"utf16_col":6},"end":{"line_number":1354,"utf16_col":25}},"extent_utf16":{"start":{"line_number":1354,"utf16_col":0},"end":{"line_number":1358,"utf16_col":0}}},{"name":"Field reference","kind":"section_4","ident_start":72334,"ident_end":72349,"extent_start":72329,"extent_end":73398,"fully_qualified_name":"Field reference","ident_utf16":{"start":{"line_number":1358,"utf16_col":5},"end":{"line_number":1358,"utf16_col":20}},"extent_utf16":{"start":{"line_number":1358,"utf16_col":0},"end":{"line_number":1383,"utf16_col":0}}},{"name":"Controller behavior","kind":"section_5","ident_start":73094,"ident_end":73113,"extent_start":73088,"extent_end":73398,"fully_qualified_name":"Controller behavior","ident_utf16":{"start":{"line_number":1374,"utf16_col":6},"end":{"line_number":1374,"utf16_col":25}},"extent_utf16":{"start":{"line_number":1374,"utf16_col":0},"end":{"line_number":1383,"utf16_col":0}}},{"name":"HTTP Status codes","kind":"section_2","ident_start":73401,"ident_end":73418,"extent_start":73398,"extent_end":78055,"fully_qualified_name":"HTTP Status codes","ident_utf16":{"start":{"line_number":1383,"utf16_col":3},"end":{"line_number":1383,"utf16_col":20}},"extent_utf16":{"start":{"line_number":1383,"utf16_col":0},"end":{"line_number":1509,"utf16_col":0}}},{"name":"Success codes","kind":"section_4","ident_start":73649,"ident_end":73662,"extent_start":73644,"extent_end":73994,"fully_qualified_name":"Success codes","ident_utf16":{"start":{"line_number":1390,"utf16_col":5},"end":{"line_number":1390,"utf16_col":18}},"extent_utf16":{"start":{"line_number":1390,"utf16_col":0},"end":{"line_number":1401,"utf16_col":0}}},{"name":"Error codes","kind":"section_4","ident_start":73999,"ident_end":74010,"extent_start":73994,"extent_end":78055,"fully_qualified_name":"Error codes","ident_utf16":{"start":{"line_number":1401,"utf16_col":5},"end":{"line_number":1401,"utf16_col":16}},"extent_utf16":{"start":{"line_number":1401,"utf16_col":0},"end":{"line_number":1509,"utf16_col":0}}},{"name":"Response Status Kind","kind":"section_2","ident_start":78058,"ident_end":78078,"extent_start":78055,"extent_end":85025,"fully_qualified_name":"Response Status Kind","ident_utf16":{"start":{"line_number":1509,"utf16_col":3},"end":{"line_number":1509,"utf16_col":23}},"extent_utf16":{"start":{"line_number":1509,"utf16_col":0},"end":{"line_number":1697,"utf16_col":0}}},{"name":"Events","kind":"section_2","ident_start":85028,"ident_end":85034,"extent_start":85025,"extent_end":85915,"fully_qualified_name":"Events","ident_utf16":{"start":{"line_number":1697,"utf16_col":3},"end":{"line_number":1697,"utf16_col":9}},"extent_utf16":{"start":{"line_number":1697,"utf16_col":0},"end":{"line_number":1716,"utf16_col":0}}},{"name":"Naming conventions","kind":"section_2","ident_start":85918,"ident_end":85936,"extent_start":85915,"extent_end":88481,"fully_qualified_name":"Naming conventions","ident_utf16":{"start":{"line_number":1716,"utf16_col":3},"end":{"line_number":1716,"utf16_col":21}},"extent_utf16":{"start":{"line_number":1716,"utf16_col":0},"end":{"line_number":1760,"utf16_col":0}}},{"name":"Namespace Names","kind":"section_3","ident_start":88109,"ident_end":88124,"extent_start":88105,"extent_end":88481,"fully_qualified_name":"Namespace Names","ident_utf16":{"start":{"line_number":1752,"utf16_col":4},"end":{"line_number":1752,"utf16_col":19}},"extent_utf16":{"start":{"line_number":1752,"utf16_col":0},"end":{"line_number":1760,"utf16_col":0}}},{"name":"Label, selector, and annotation conventions","kind":"section_2","ident_start":88484,"ident_end":88527,"extent_start":88481,"extent_end":95613,"fully_qualified_name":"Label, selector, and annotation conventions","ident_utf16":{"start":{"line_number":1760,"utf16_col":3},"end":{"line_number":1760,"utf16_col":46}},"extent_utf16":{"start":{"line_number":1760,"utf16_col":0},"end":{"line_number":1868,"utf16_col":0}}},{"name":"WebSockets and SPDY","kind":"section_2","ident_start":95616,"ident_end":95635,"extent_start":95613,"extent_end":98025,"fully_qualified_name":"WebSockets and SPDY","ident_utf16":{"start":{"line_number":1868,"utf16_col":3},"end":{"line_number":1868,"utf16_col":22}},"extent_utf16":{"start":{"line_number":1868,"utf16_col":0},"end":{"line_number":1911,"utf16_col":0}}},{"name":"Validation","kind":"section_2","ident_start":98028,"ident_end":98038,"extent_start":98025,"extent_end":99589,"fully_qualified_name":"Validation","ident_utf16":{"start":{"line_number":1911,"utf16_col":3},"end":{"line_number":1911,"utf16_col":13}},"extent_utf16":{"start":{"line_number":1911,"utf16_col":0},"end":{"line_number":1940,"utf16_col":0}}},{"name":"Automatic Resource Allocation And Deallocation","kind":"section_2","ident_start":99592,"ident_end":99638,"extent_start":99589,"extent_end":101217,"fully_qualified_name":"Automatic Resource Allocation And Deallocation","ident_utf16":{"start":{"line_number":1940,"utf16_col":3},"end":{"line_number":1940,"utf16_col":49}},"extent_utf16":{"start":{"line_number":1940,"utf16_col":0},"end":{"line_number":1963,"utf16_col":0}}},{"name":"Representing Allocated Values","kind":"section_2","ident_start":101220,"ident_end":101249,"extent_start":101217,"extent_end":107420,"fully_qualified_name":"Representing Allocated Values","ident_utf16":{"start":{"line_number":1963,"utf16_col":3},"end":{"line_number":1963,"utf16_col":32}},"extent_utf16":{"start":{"line_number":1963,"utf16_col":0},"end":{"line_number":2080,"utf16_col":0}}},{"name":"When to use a `spec` field","kind":"section_3","ident_start":103945,"ident_end":103971,"extent_start":103941,"extent_end":104111,"fully_qualified_name":"When to use a `spec` field","ident_utf16":{"start":{"line_number":2012,"utf16_col":4},"end":{"line_number":2012,"utf16_col":30}},"extent_utf16":{"start":{"line_number":2012,"utf16_col":0},"end":{"line_number":2017,"utf16_col":0}}},{"name":"When to use a `status` field","kind":"section_3","ident_start":104115,"ident_end":104143,"extent_start":104111,"extent_end":106098,"fully_qualified_name":"When to use a `status` field","ident_utf16":{"start":{"line_number":2017,"utf16_col":4},"end":{"line_number":2017,"utf16_col":32}},"extent_utf16":{"start":{"line_number":2017,"utf16_col":0},"end":{"line_number":2054,"utf16_col":0}}},{"name":"Sequencing operations","kind":"section_4","ident_start":104847,"ident_end":104868,"extent_start":104842,"extent_end":106098,"fully_qualified_name":"Sequencing operations","ident_utf16":{"start":{"line_number":2033,"utf16_col":5},"end":{"line_number":2033,"utf16_col":26}},"extent_utf16":{"start":{"line_number":2033,"utf16_col":0},"end":{"line_number":2054,"utf16_col":0}}},{"name":"When to use a different type","kind":"section_3","ident_start":106102,"ident_end":106130,"extent_start":106098,"extent_end":107420,"fully_qualified_name":"When to use a different type","ident_utf16":{"start":{"line_number":2054,"utf16_col":4},"end":{"line_number":2054,"utf16_col":32}},"extent_utf16":{"start":{"line_number":2054,"utf16_col":0},"end":{"line_number":2080,"utf16_col":0}}}]}},"copilotInfo":null,"copilotAccessAllowed":false,"modelsAccessAllowed":false,"csrf_tokens":{"/kubernetes/community/branches":{"post":"D1BMc1DMg87W2j5XQ7THtRGMNulQQfjjVX_3Ha-82BLocD4eNdTCylb9X5qtoU1OmazreG3TFg_xqw0YswKLgA"},"/repos/preferences":{"post":"ST8caA1rEKNt_JqkZVhzEv_H7IjY9TS1KfcUe7upv6JKZ7tkF03f_d_IMf1cnYt3-mqjuNO6pZWGsGwzy9JrcA"}}},"title":"community/contributors/devel/sig-architecture/api-conventions.md at master · kubernetes/community","appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-9f8a877aa99f.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-96e76d5fdb2c.js","githubDevUrl":null,"enabled_features":{"code_nav_ui_events":false,"overview_shared_code_dropdown_button":false,"react_blob_overlay":false,"copilot_conversational_ux_embedding_update":false,"copilot_smell_icebreaker_ux":true,"accessible_code_button":true}}}</script> <div data-target="react-app.reactRoot"><style data-styled="true" data-styled-version="5.3.11">.hOfjFo{padding:0;}/*!sc*/ .oDGAe{max-width:100%;margin-left:auto;margin-right:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}/*!sc*/ .kowOcT{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 100%;-ms-flex:1 1 100%;flex:1 1 100%;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;}/*!sc*/ .gISSDQ{width:100%;}/*!sc*/ @media screen and (min-width:544px){.gISSDQ{width:100%;}}/*!sc*/ @media screen and (min-width:768px){.gISSDQ{width:auto;}}/*!sc*/ .cEmWSE{display:none;-webkit-order:1;-ms-flex-order:1;order:1;width:100%;margin-left:0;margin-right:0;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;margin-bottom:0;min-width:0;}/*!sc*/ @media screen and (min-width:768px){.cEmWSE{width:auto;margin-top:0 !important;margin-bottom:0 !important;position:-webkit-sticky;position:sticky;top:0px;max-height:100vh !important;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;margin-right:0;height:100vh;}}/*!sc*/ @media print,screen and (max-width:1011px) and (min-width:768px){.cEmWSE{display:none;}}/*!sc*/ .hPvFuC{margin-left:0;margin-right:0;display:none;margin-top:0;}/*!sc*/ @media screen and (min-width:768px){.hPvFuC{margin-left:0 !important;margin-right:0 !important;}}/*!sc*/ .fFSoPl{--pane-min-width:256px;--pane-max-width-diff:511px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));width:100%;padding:0;}/*!sc*/ @media screen and (min-width:544px){}/*!sc*/ @media screen and (min-width:768px){.fFSoPl{width:clamp(var(--pane-min-width),var(--pane-width),var(--pane-max-width));overflow:auto;}}/*!sc*/ @media screen and (min-width:1280px){.fFSoPl{--pane-max-width-diff:959px;}}/*!sc*/ .bTBnTW{height:100%;position:relative;display:none;margin-left:0;}/*!sc*/ .bHLmSv{position:absolute;inset:0 -2px;cursor:col-resize;background-color:transparent;-webkit-transition-delay:0.1s;transition-delay:0.1s;}/*!sc*/ .bHLmSv:hover{background-color:var(--bgColor-neutral-muted,var(--color-neutral-muted,rgba(175,184,193,0.2)));}/*!sc*/ .iKqMNA{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-order:2;-ms-flex-order:2;order:2;-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;min-width:1px;margin-right:auto;}/*!sc*/ @media print{.iKqMNA{display:-webkit-box !important;display:-webkit-flex !important;display:-ms-flexbox !important;display:flex !important;}}/*!sc*/ .FxAyp{width:100%;max-width:100%;margin-left:auto;margin-right:auto;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0;}/*!sc*/ .leYMvG{margin-left:auto;margin-right:auto;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-bottom:40px;max-width:100%;margin-top:0;}/*!sc*/ .KMPzq{display:inherit;}/*!sc*/ .hfKjHv{width:100%;}/*!sc*/ .gZWyZE{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:8px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;}/*!sc*/ .dwYKDk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;gap:8px;}/*!sc*/ .ibcGmb{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;min-width:0;}/*!sc*/ .hKaEJF{display:block;margin-right:8px;}/*!sc*/ @media screen and (min-width:1360px){.hKaEJF{display:block;}}/*!sc*/ .XosP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:14px;}/*!sc*/ .bCKfWo[data-size="medium"]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));padding-left:8px;padding-right:8px;display:none;}/*!sc*/ @media screen and (max-width:768px){.bCKfWo[data-size="medium"]{display:block;}}/*!sc*/ .gUkoLg{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/ .dmxRgG[data-size="medium"]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ .dmxRgG[data-size="medium"] svg{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dmxRgG[data-size="medium"] > span{width:inherit;}/*!sc*/ .bZBlpz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;}/*!sc*/ .lhTYNA{margin-right:4px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dbrgmi{font-size:14px;min-width:0;max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}/*!sc*/ .dHJiml{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:8px;padding-right:8px;min-width:0;}/*!sc*/ .cEytCf{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:16px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .fzFXnm{max-width:100%;}/*!sc*/ .iMnkmv{max-width:100%;list-style:none;display:inline-block;}/*!sc*/ .ghzDag{display:inline-block;max-width:100%;}/*!sc*/ .kHuKdh{font-weight:600;}/*!sc*/ .kgiVEz{font-weight:400;}/*!sc*/ .jGhzSQ{font-weight:600;display:inline-block;max-width:100%;font-size:16px;}/*!sc*/ .faNtbn{min-height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;}/*!sc*/ .fmQaBv{margin-left:4px;margin-right:4px;}/*!sc*/ .dwNhzn[data-size="medium"][data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;display:none;}/*!sc*/ .fGwBZA[data-size="medium"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dJxjrT{margin-left:16px;margin-right:16px;}/*!sc*/ .eFxKDQ{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}/*!sc*/ .dzCJzi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:273px;padding:8px;}/*!sc*/ @media screen and (min-width:544px){.dzCJzi{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;}}/*!sc*/ .ldRxiI{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}/*!sc*/ .fVkfyA{width:100%;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;min-width:0;margin-right:0;}/*!sc*/ .gNAmSV{height:40px;padding-left:4px;padding-bottom:16px;}/*!sc*/ .jNEwzY{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .bsDwxw{font-size:12px;-webkit-flex:auto;-ms-flex:auto;flex:auto;padding-right:16px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));min-width:0;}/*!sc*/ .jdLMhu{top:0px;z-index:4;background:var(--bgColor-default,var(--color-canvas-default));position:-webkit-sticky;position:sticky;}/*!sc*/ .tOISc{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;position:absolute;}/*!sc*/ .hqwSEx{display:none;min-width:0;padding-top:8px;padding-bottom:8px;}/*!sc*/ .bDVoEr{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;margin-left:8px;margin-right:8px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;width:100%;}/*!sc*/ .kYLlPM{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .gYjEmn{margin-left:4px;margin-right:8px;}/*!sc*/ .kGqOLL{text-overflow:ellipsis;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ .fHind{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:14px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .dnZoUW{font-weight:600;display:inline-block;max-width:100%;font-size:14px;}/*!sc*/ .jRZWlf[data-size="small"]{color:var(--fgColor-default,var(--color-fg-default,#1F2328));margin-left:8px;}/*!sc*/ .kTvpNk{padding-left:8px;padding-top:8px;padding-bottom:8px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background-color:var(--bgColor-muted,var(--color-canvas-subtle,#f6f8fa));border:1px solid var(--borderColor-default,var(--color-border-default));border-radius:6px 6px 0px 0px;}/*!sc*/ .iNMjfP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:0;}/*!sc*/ .fefCSX{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:transparent;}/*!sc*/ .fefCSX:not(:last-child){margin-right:1px;}/*!sc*/ .fefCSX:not(:last-child):after{background-color:var(--separator-color);content:"";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/ .fefCSX:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/ .fefCSX:first-child{margin-left:-1px;}/*!sc*/ .fefCSX:last-child{margin-right:-1px;}/*!sc*/ .idgUkN{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:var(--borderColor-default,var(--color-border-default,#d0d7de));}/*!sc*/ .idgUkN:not(:last-child){margin-right:1px;}/*!sc*/ .idgUkN:not(:last-child):after{background-color:var(--separator-color);content:"";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/ .idgUkN:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/ .idgUkN:first-child{margin-left:-1px;}/*!sc*/ .idgUkN:last-child{margin-right:-1px;}/*!sc*/ .kcLCKF{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;margin-right:8px;}/*!sc*/ .kVWtTz{gap:8px;}/*!sc*/ .gWqxTd{padding-left:8px;padding-right:8px;}/*!sc*/ .gWqxTd linkButtonSx:hover:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .gWqxTd linkButtonSx:focus:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .gWqxTd linkButtonSx:active:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .ivobqY[data-size="small"][data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;}/*!sc*/ .iNRSob[data-size="small"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted));margin-right:8px;}/*!sc*/ .ffkqe[data-size="small"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .hGyMdv{border:1px solid;border-top:none;border-color:var(--borderColor-default,var(--color-border-default,#d0d7de));border-radius:0px 0px 6px 6px;min-width:273px;}/*!sc*/ .fGqKFv{background-color:var(--bgColor-default,var(--color-canvas-default));border:0px;border-width:0;border-radius:0px 0px 6px 6px;padding:0;min-width:0;margin-top:46px;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/ .eoaCFS{border-bottom-left-radius:6px;border-bottom-right-radius:6px;padding:32px;min-width:0;}/*!sc*/ .cCoXib{position:fixed;top:0;right:0;height:100%;width:15px;-webkit-transition:-webkit-transform 0.3s;-webkit-transition:transform 0.3s;transition:transform 0.3s;z-index:1;}/*!sc*/ .cCoXib:hover{-webkit-transform:scaleX(1.5);-ms-transform:scaleX(1.5);transform:scaleX(1.5);}/*!sc*/ data-styled.g1[id="Box-sc-g0xbh4-0"]{content:"hOfjFo,oDGAe,kowOcT,gISSDQ,cEmWSE,hPvFuC,fFSoPl,bTBnTW,bHLmSv,iKqMNA,FxAyp,leYMvG,KMPzq,hfKjHv,gZWyZE,dwYKDk,ibcGmb,hKaEJF,XosP,bCKfWo,gUkoLg,dmxRgG,bZBlpz,lhTYNA,dbrgmi,dHJiml,cEytCf,fzFXnm,iMnkmv,ghzDag,kHuKdh,kgiVEz,jGhzSQ,faNtbn,fmQaBv,dwNhzn,fGwBZA,dJxjrT,eFxKDQ,dzCJzi,ldRxiI,fVkfyA,gNAmSV,jNEwzY,bsDwxw,jdLMhu,tOISc,hqwSEx,bDVoEr,kYLlPM,gYjEmn,kGqOLL,fHind,dnZoUW,jRZWlf,kTvpNk,iNMjfP,fefCSX,idgUkN,kcLCKF,kVWtTz,gWqxTd,ivobqY,iNRSob,ffkqe,hGyMdv,fGqKFv,eoaCFS,cCoXib,"}/*!sc*/ .eMMFM{min-width:0;}/*!sc*/ .eMMFM:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .eMMFM:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .eMMFM:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .eMMFM:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .eMMFM:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .eMMFM:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .eMMFM:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ .HlHVj{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:16px;}/*!sc*/ .HlHVj:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .HlHVj:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .HlHVj:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .HlHVj:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .HlHVj:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .HlHVj:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .HlHVj:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ .lauzFl{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:14px;}/*!sc*/ .lauzFl:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .lauzFl:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .lauzFl:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .lauzFl:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .lauzFl:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .lauzFl:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .lauzFl:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ data-styled.g3[id="Text__StyledText-sc-17v1xeu-0"]{content:"eMMFM,HlHVj,lauzFl,"}/*!sc*/ .jkNcAv{border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;}/*!sc*/ .jkNcAv:focus{outline:0;}/*!sc*/ data-styled.g13[id="UnstyledTextInput__ToggledUnstyledTextInput-sc-14ypya-0"]{content:"jkNcAv,"}/*!sc*/ .hLzFvi{font-size:14px;line-height:var(--base-size-20);color:var(--fgColor-default,var(--color-fg-default,#1F2328));vertical-align:middle;background-color:var(--bgColor-default,var(--color-canvas-default,#ffffff));border:1px solid var(--control-borderColor-rest,var(--borderColor-default,var(--color-border-default,#d0d7de)));border-radius:6px;outline:none;box-shadow:var(--shadow-inset,var(--color-primer-shadow-inset,inset 0 1px 0 rgba(208,215,222,0.2)));display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:stretch;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;min-height:var(--base-size-32);overflow:hidden;--inner-action-size:var(--base-size-24);}/*!sc*/ .hLzFvi input,.hLzFvi textarea{cursor:text;}/*!sc*/ .hLzFvi select{cursor:pointer;}/*!sc*/ .hLzFvi input::-webkit-input-placeholder,.hLzFvi textarea::-webkit-input-placeholder,.hLzFvi select::-webkit-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input::-moz-placeholder,.hLzFvi textarea::-moz-placeholder,.hLzFvi select::-moz-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input:-ms-input-placeholder,.hLzFvi textarea:-ms-input-placeholder,.hLzFvi select:-ms-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input::placeholder,.hLzFvi textarea::placeholder,.hLzFvi select::placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi:where([data-trailing-action][data-focused]),.hLzFvi:where(:not([data-trailing-action]):focus-within){border-color:var(--fgColor-accent,var(--color-accent-fg,#0969da));outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .hLzFvi > textarea{padding:var(--base-size-12);}/*!sc*/ .hLzFvi:where([data-contrast]){background-color:var(--bgColor-inset,var(--color-canvas-inset,#f6f8fa));}/*!sc*/ .hLzFvi:where([data-disabled]){color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#8c959f));background-color:var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(175,184,193,0.2)));box-shadow:none;border-color:var(--control-borderColor-disabled,var(--borderColor-default,var(--color-border-default,#d0d7de)));}/*!sc*/ .hLzFvi:where([data-disabled]) input,.hLzFvi:where([data-disabled]) textarea,.hLzFvi:where([data-disabled]) select{cursor:not-allowed;}/*!sc*/ .hLzFvi:where([data-monospace]){font-family:var(--fontStack-monospace,SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace);}/*!sc*/ .hLzFvi:where([data-validation='error']){border-color:var(--borderColor-danger-emphasis,var(--color-danger-emphasis,#cf222e));}/*!sc*/ .hLzFvi:where([data-validation='error']):where([data-trailing-action][data-focused]),.hLzFvi:where([data-validation='error']):where(:not([data-trailing-action])):focus-within{border-color:var(--fgColor-accent,var(--color-accent-fg,#0969da));outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .hLzFvi:where([data-validation='success']){border-color:var(--bgColor-success-emphasis,var(--color-success-emphasis,#1f883d));}/*!sc*/ .hLzFvi:where([data-block]){width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;}/*!sc*/ @media (min-width:768px){.hLzFvi{font-size:var(--text-body-size-medium);}}/*!sc*/ .hLzFvi:where([data-size='small']){--inner-action-size:var(--base-size-20);min-height:var(--base-size-28);padding-top:3px;padding-right:var(--base-size-8);padding-bottom:3px;padding-left:var(--base-size-8);font-size:var(--text-body-size-small);line-height:var(--base-size-20);}/*!sc*/ .hLzFvi:where([data-size='large']){--inner-action-size:var(--base-size-28);height:var(--base-size-40);padding-top:10px;padding-right:var(--base-size-8);padding-bottom:10px;padding-left:var(--base-size-8);}/*!sc*/ .hLzFvi:where([data-variant='small']){min-height:28px;padding-top:3px;padding-right:var(--base-size-8);padding-bottom:3px;padding-left:var(--base-size-8);font-size:(--text-body-size-small);line-height:var(--base-size-20);}/*!sc*/ .hLzFvi:where([data-variant='large']){padding-top:10px;padding-right:var(--base-size-8);padding-bottom:10px;padding-left:var(--base-size-8);font-size:var(--text-title-size-medium);}/*!sc*/ .hLzFvi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/ data-styled.g14[id="TextInputWrapper__StyledTextInputBaseWrapper-sc-1mqhpbi-0"]{content:"hLzFvi,"}/*!sc*/ .iHYdQq{background-repeat:no-repeat;background-position:right 8px center;padding-right:0;padding-left:0;}/*!sc*/ .iHYdQq > :not(:last-child){margin-right:8px;}/*!sc*/ .iHYdQq .TextInput-icon,.iHYdQq .TextInput-action{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}/*!sc*/ .iHYdQq > input,.iHYdQq > select{padding-right:0;padding-left:0;}/*!sc*/ .iHYdQq:where([data-leading-visual]){padding-left:var(--base-size-12);}/*!sc*/ .iHYdQq:where([data-trailing-visual]:not([data-trailing-action])){padding-right:var(--base-size-12);}/*!sc*/ .iHYdQq:where(:not([data-leading-visual])) > input,.iHYdQq:where(:not([data-leading-visual])) > select{padding-left:var(--base-size-12);}/*!sc*/ .iHYdQq:where(:not([data-trailing-visual]):not([data-trailing-action])) > input,.iHYdQq:where(:not([data-trailing-visual]):not([data-trailing-action])) > select{padding-right:var(--base-size-12);}/*!sc*/ .iHYdQq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/ data-styled.g15[id="TextInputWrapper__StyledTextInputWrapper-sc-1mqhpbi-1"]{content:"iHYdQq,"}/*!sc*/ .jOyaRH{display:none;}/*!sc*/ .jOyaRH[popover]{position:absolute;padding:0.5em 0.75em;width:-webkit-max-content;width:-moz-max-content;width:max-content;margin:auto;-webkit-clip:auto;clip:auto;white-space:normal;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:var(--tooltip-fgColor,var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff)));text-align:center;word-wrap:break-word;background:var(--tooltip-bgColor,var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#24292f)));border-radius:6px;border:0;opacity:0;max-width:250px;inset:auto;overflow:visible;}/*!sc*/ .jOyaRH[popover]:popover-open{display:block;}/*!sc*/ .jOyaRH[popover].\:popover-open{display:block;}/*!sc*/ @media (forced-colors:active){.jOyaRH{outline:1px solid transparent;}}/*!sc*/ .jOyaRH::after{position:absolute;display:block;right:0;left:0;height:var(--overlay-offset,0.25rem);content:'';}/*!sc*/ .jOyaRH[data-direction='n']::after,.jOyaRH[data-direction='ne']::after,.jOyaRH[data-direction='nw']::after{top:100%;}/*!sc*/ .jOyaRH[data-direction='s']::after,.jOyaRH[data-direction='se']::after,.jOyaRH[data-direction='sw']::after{bottom:100%;}/*!sc*/ .jOyaRH[data-direction='w']::after{position:absolute;display:block;height:100%;width:8px;content:'';bottom:0;left:100%;}/*!sc*/ .jOyaRH[data-direction='e']::after{position:absolute;display:block;height:100%;width:8px;content:'';bottom:0;right:100%;margin-left:-8px;}/*!sc*/ @-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ @keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ .jOyaRH:popover-open,.jOyaRH:popover-open::before{-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .jOyaRH.\:popover-open,.jOyaRH.\:popover-open::before{-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ data-styled.g16[id="Tooltip__StyledTooltip-sc-e45c7z-0"]{content:"jOyaRH,"}/*!sc*/ .hWlpPn{position:relative;display:inline-block;}/*!sc*/ .hWlpPn::after{position:absolute;z-index:1000000;display:none;padding:0.5em 0.75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:var(--tooltip-fgColor,var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff)));text-align:center;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;text-transform:none;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:var(--tooltip-bgColor,var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#24292f)));border-radius:6px;opacity:0;}/*!sc*/ @-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ @keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ .hWlpPn:hover::after,.hWlpPn:active::after,.hWlpPn:focus::after,.hWlpPn:focus-within::after{display:inline-block;-webkit-text-decoration:none;text-decoration:none;-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-no-delay:hover::after,.hWlpPn.tooltipped-no-delay:active::after,.hWlpPn.tooltipped-no-delay:focus::after,.hWlpPn.tooltipped-no-delay:focus-within::after{-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-multiline:hover::after,.hWlpPn.tooltipped-multiline:active::after,.hWlpPn.tooltipped-multiline:focus::after,.hWlpPn.tooltipped-multiline:focus-within::after{display:table-cell;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-se::after,.hWlpPn.tooltipped-sw::after{top:100%;right:50%;margin-top:6px;}/*!sc*/ .hWlpPn.tooltipped-se::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-sw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-n::after,.hWlpPn.tooltipped-ne::after,.hWlpPn.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:6px;}/*!sc*/ .hWlpPn.tooltipped-ne::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-nw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-n::after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%);}/*!sc*/ .hWlpPn.tooltipped-w::after{right:100%;bottom:50%;margin-right:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-e::after{bottom:50%;left:100%;margin-left:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-wrap:break-word;white-space:pre-line;border-collapse:separate;}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-s::after,.hWlpPn.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-w::after,.hWlpPn.tooltipped-multiline.tooltipped-e::after{right:100%;}/*!sc*/ .hWlpPn.tooltipped-align-right-2::after{right:0;margin-right:0;}/*!sc*/ .hWlpPn.tooltipped-align-left-2::after{left:0;margin-left:0;}/*!sc*/ data-styled.g17[id="Tooltip__TooltipBase-sc-17tf59c-0"]{content:"hWlpPn,"}/*!sc*/ .eAtkQz{display:inline-block;overflow:hidden;text-overflow:ellipsis;vertical-align:top;white-space:nowrap;max-width:125px;max-width:100%;}/*!sc*/ data-styled.g19[id="Truncate__StyledTruncate-sc-23o1d2-0"]{content:"eAtkQz,"}/*!sc*/ .dwImxt{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:600;padding:0;height:100%;width:100%;}/*!sc*/ .dwImxt:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .dwImxt:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .dwImxt:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .dwImxt .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg,#ffffff));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-hover-active-selected-border,#8c959f));border-style:solid;border-width:1px;border-radius:var(--segmented-control-outer-radius);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:var(--segmented-control-button-inner-padding);padding-right:var(--segmented-control-button-inner-padding);}/*!sc*/ .dwImxt svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dwImxt:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .dwImxt .segmentedControl-text:after{content:"Preview";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.dwImxt:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ .iFTkun{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;padding:var(--segmented-control-button-bg-inset);height:100%;width:100%;}/*!sc*/ .iFTkun:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .iFTkun:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .iFTkun:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .iFTkun .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:transparent;border-color:transparent;border-style:solid;border-width:1px;border-radius:calc(var(--segmented-control-outer-radius) - var(--segmented-control-button-bg-inset) / 2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));padding-right:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));}/*!sc*/ .iFTkun svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .iFTkun:hover .segmentedControl-content{background-color:var(--controlTrack-bgColor-hover,var(--color-segmented-control-button-hover-bg,rgba(175,184,193,0.2)));}/*!sc*/ .iFTkun:active .segmentedControl-content{background-color:var(--controlTrack-bgColor-active,var(--color-segmented-control-button-hover-active-bg,rgba(175,184,193,0.4)));}/*!sc*/ .iFTkun:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .iFTkun .segmentedControl-text:after{content:"Code";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.iFTkun:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ .bHmvop{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;padding:var(--segmented-control-button-bg-inset);height:100%;width:100%;}/*!sc*/ .bHmvop:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .bHmvop:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .bHmvop:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .bHmvop .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:transparent;border-color:transparent;border-style:solid;border-width:1px;border-radius:calc(var(--segmented-control-outer-radius) - var(--segmented-control-button-bg-inset) / 2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));padding-right:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));}/*!sc*/ .bHmvop svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .bHmvop:hover .segmentedControl-content{background-color:var(--controlTrack-bgColor-hover,var(--color-segmented-control-button-hover-bg,rgba(175,184,193,0.2)));}/*!sc*/ .bHmvop:active .segmentedControl-content{background-color:var(--controlTrack-bgColor-active,var(--color-segmented-control-button-hover-active-bg,rgba(175,184,193,0.4)));}/*!sc*/ .bHmvop:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .bHmvop .segmentedControl-text:after{content:"Blame";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.bHmvop:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ data-styled.g105[id="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0"]{content:"dwImxt,iFTkun,bHmvop,"}/*!sc*/ .lawgDG{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg,#eaeef2));border-radius:6px;border:1px solid;border-color:var(--controlTrack-borderColor-rest,transparent);display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;font-size:14px;height:28px;margin:0;padding:0;}/*!sc*/ data-styled.g107[id="SegmentedControl__SegmentedControlList-sc-1rzig82-0"]{content:"lawgDG,"}/*!sc*/ body[data-page-layout-dragging="true"]{cursor:col-resize;}/*!sc*/ body[data-page-layout-dragging="true"] *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}/*!sc*/ data-styled.g108[id="sc-global-gbKrvU1"]{content:"sc-global-gbKrvU1,"}/*!sc*/ </style><meta data-hydrostats="publish"/> <!-- --> <!-- --> <button hidden="" data-testid="header-permalink-button" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button><div><div style="--sticky-pane-height:100vh;--spacing:var(--spacing-none)" class="Box-sc-g0xbh4-0 hOfjFo"><div class="Box-sc-g0xbh4-0 oDGAe"><div class="Box-sc-g0xbh4-0 kowOcT"><div tabindex="0" class="Box-sc-g0xbh4-0 gISSDQ"><div class="Box-sc-g0xbh4-0 cEmWSE"><div class="Box-sc-g0xbh4-0 hPvFuC"></div><div style="--pane-width:320px" class="Box-sc-g0xbh4-0 fFSoPl"></div><div class="Box-sc-g0xbh4-0 bTBnTW"><div role="slider" aria-label="Draggable pane splitter" aria-valuemin="0" aria-valuemax="0" aria-valuenow="0" aria-valuetext="Pane width 0 pixels" tabindex="0" class="Box-sc-g0xbh4-0 bHLmSv"></div></div></div></div><div class="Box-sc-g0xbh4-0 iKqMNA"><div class="Box-sc-g0xbh4-0"></div><div class="Box-sc-g0xbh4-0 FxAyp"><div data-selector="repos-split-pane-content" tabindex="0" class="Box-sc-g0xbh4-0 leYMvG"><div class="Box-sc-g0xbh4-0 KMPzq"><div class="Box-sc-g0xbh4-0 hfKjHv container"><div class="px-3 pt-3 pb-0" id="StickyHeader"><div class="Box-sc-g0xbh4-0 gZWyZE"><div class="Box-sc-g0xbh4-0 dwYKDk"><div class="Box-sc-g0xbh4-0 ibcGmb react-code-view-header-wrap--narrow"><div class="Box-sc-g0xbh4-0 hKaEJF"><h2 class="Box-sc-g0xbh4-0 XosP prc-Heading-Heading-6CmGO"><button style="--button-color:fg.muted" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="Box-sc-g0xbh4-0 bCKfWo prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="invisible" aria-describedby=":Rld9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Files</span></span></button><span role="tooltip" aria-label="Expand file tree" id="expand-button-file-tree-button" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-se"><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-c50BI position-relative ExpandFileTreeButton-module__expandButton--gL4is ExpandFileTreeButton-module__filesButtonBreakpoint--WfX9t fgColor-muted prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-describedby=":R35d9lab:-loading-announcement" aria-labelledby="expand-button-file-tree-button"><svg aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button></span><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" class="Box-sc-g0xbh4-0 dmxRgG prc-Button-ButtonBase-c50BI ref-selector-class" data-loading="false" data-size="medium" data-variant="default" aria-describedby="branch-picker-repos-header-ref-selector-wide-loading-announcement" id="branch-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x"><div class="Box-sc-g0xbh4-0 bZBlpz"><div class="Box-sc-g0xbh4-0 lhTYNA"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></div><div class="Box-sc-g0xbh4-0 dbrgmi ref-selector-button-text-container"><span class="Text__StyledText-sc-17v1xeu-0 eMMFM"> <!-- -->master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><button hidden="" data-hotkey-scope="read-only-cursor-text-area"></button></div><div class="Box-sc-g0xbh4-0 dHJiml react-code-view-header-mb--narrow"><div class="Box-sc-g0xbh4-0 cEytCf"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Box-sc-g0xbh4-0 fzFXnm"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Box-sc-g0xbh4-0 iMnkmv"><li class="Box-sc-g0xbh4-0 ghzDag"><a class="Box-sc-g0xbh4-0 kHuKdh prc-Link-Link-85e08" sx="[object Object]" data-testid="breadcrumbs-repo-link" href="/kubernetes/community/tree/master">community</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors">contributors</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors/devel">devel</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors/devel/sig-architecture">sig-architecture</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><h1 class="Box-sc-g0xbh4-0 jGhzSQ prc-Heading-Heading-6CmGO" tabindex="-1" id="file-name-id">api-conventions.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-c50BI ml-2 prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":Rftd9lab:-loading-announcement" aria-labelledby=":R1td9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="Tooltip__StyledTooltip-sc-e45c7z-0 jOyaRH CopyToClipboardButton-module__tooltip--Dq1IB" data-direction="nw" aria-label="Copy path" aria-hidden="true" id=":R1td9lab:">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="Box-sc-g0xbh4-0 faNtbn"><div class="d-flex gap-2"> <div><div class="Box-sc-g0xbh4-0 fmQaBv"><span class="TextInputWrapper__StyledTextInputBaseWrapper-sc-1mqhpbi-0 hLzFvi TextInputWrapper__StyledTextInputWrapper-sc-1mqhpbi-1 iHYdQq TextInput-wrapper" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id=":R5j6d9lab:" aria-hidden="true"><svg aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellcheck="false" placeholder="Go to file" aria-describedby=":R5j6d9lab: :R5j6d9labH1:" data-component="input" class="UnstyledTextInput__ToggledUnstyledTextInput-sc-14ypya-0 jkNcAv" value=""/><span class="TextInput-icon" id=":R5j6d9labH1:" aria-hidden="true"></span></span></div><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button></div><button type="button" class="Box-sc-g0xbh4-0 dwNhzn prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R2l6d9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Blame</span></span></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button data-component="IconButton" type="button" aria-label="More file actions" title="More file actions" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R156d9lab:-loading-announcement" id=":R156d9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button> </div></div></div><div class="react-code-view-header-element--narrow"><div class="Box-sc-g0xbh4-0 faNtbn"><div class="d-flex gap-2"> <button type="button" class="Box-sc-g0xbh4-0 dwNhzn prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R2l7d9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Blame</span></span></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button data-component="IconButton" type="button" aria-label="More file actions" title="More file actions" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R157d9lab:-loading-announcement" id=":R157d9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button> </div></div></div></div></div></div></div></div><div class="Box-sc-g0xbh4-0 dJxjrT react-code-view-bottom-padding"> <div class="Box-sc-g0xbh4-0 eFxKDQ"></div> <!-- --> <!-- --> </div><div class="Box-sc-g0xbh4-0 dJxjrT"> <!-- --> <!-- --> <button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button><div class="d-flex flex-column border rounded-2 mb-3 pl-1"><div class="Box-sc-g0xbh4-0 dzCJzi"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">History</h2><a href="/kubernetes/community/commits/master/contributors/devel/sig-architecture/api-conventions.md" class="prc-Button-ButtonBase-c50BI d-none d-lg-flex LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":R5dlal9lab:-loading-announcement"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><span role="tooltip" aria-label="History" id="history-icon-button-tooltip" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-n"><a href="/kubernetes/community/commits/master/contributors/devel/sig-architecture/api-conventions.md" class="prc-Button-ButtonBase-c50BI LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":Rpdlal9lab:-loading-announcement history-icon-button-tooltip"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a></span></div></div></div></div></div><div class="Box-sc-g0xbh4-0 ldRxiI"><div class="Box-sc-g0xbh4-0 fVkfyA container"><div class="Box-sc-g0xbh4-0 gNAmSV react-code-size-details-banner"><div class="Box-sc-g0xbh4-0 jNEwzY react-code-size-details-banner"><div class="Box-sc-g0xbh4-0 bsDwxw text-mono"><div title="105 KB" data-testid="blob-size" class="Truncate__StyledTruncate-sc-23o1d2-0 eAtkQz"><span>2080 lines (1682 loc) · 105 KB</span></div></div></div></div><div class="Box-sc-g0xbh4-0 jdLMhu react-blob-view-header-sticky" id="repos-sticky-header"><div class="Box-sc-g0xbh4-0 tOISc"><div class="react-blob-sticky-header"><div class="Box-sc-g0xbh4-0 hqwSEx"><div class="Box-sc-g0xbh4-0 bDVoEr"><div class="Box-sc-g0xbh4-0 kYLlPM"><div class="Box-sc-g0xbh4-0 gYjEmn"><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" class="Box-sc-g0xbh4-0 dmxRgG prc-Button-ButtonBase-c50BI ref-selector-class" data-loading="false" data-size="medium" data-variant="default" aria-describedby="branch-picker-repos-header-ref-selector-loading-announcement" id="branch-picker-repos-header-ref-selector"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x"><div class="Box-sc-g0xbh4-0 bZBlpz"><div class="Box-sc-g0xbh4-0 lhTYNA"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></div><div class="Box-sc-g0xbh4-0 dbrgmi ref-selector-button-text-container"><span class="Text__StyledText-sc-17v1xeu-0 eMMFM"> <!-- -->master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><button hidden="" data-hotkey-scope="read-only-cursor-text-area"></button></div><div class="Box-sc-g0xbh4-0 kGqOLL"><div class="Box-sc-g0xbh4-0 fHind"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Box-sc-g0xbh4-0 fzFXnm"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Box-sc-g0xbh4-0 iMnkmv"><li class="Box-sc-g0xbh4-0 ghzDag"><a class="Box-sc-g0xbh4-0 kHuKdh prc-Link-Link-85e08" sx="[object Object]" data-testid="breadcrumbs-repo-link" href="/kubernetes/community/tree/master">community</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors">contributors</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors/devel">devel</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/kubernetes/community/tree/master/contributors/devel/sig-architecture">sig-architecture</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><h1 class="Box-sc-g0xbh4-0 dnZoUW prc-Heading-Heading-6CmGO" tabindex="-1" id="sticky-file-name-id">api-conventions.md</h1></div></div></div></div><button style="--button-color:fg.default" type="button" class="Box-sc-g0xbh4-0 jRZWlf prc-Button-ButtonBase-c50BI" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":Riptal9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Top</span></span></button></div></div></div><div class="Box-sc-g0xbh4-0 kTvpNk"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">File metadata and controls</h2><div class="Box-sc-g0xbh4-0 iNMjfP"><ul aria-label="File view" class="SegmentedControl__SegmentedControlList-sc-1rzig82-0 lawgDG" data-size="small"><li class="Box-sc-g0xbh4-0 fefCSX" data-selected="true"><button aria-current="true" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 dwImxt" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="Box-sc-g0xbh4-0 idgUkN"><button aria-current="false" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 iFTkun" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="Box-sc-g0xbh4-0 idgUkN"><button aria-current="false" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 bHmvop" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><div class="Box-sc-g0xbh4-0 jNEwzY react-code-size-details-in-header"><div class="Box-sc-g0xbh4-0 bsDwxw text-mono"><div title="105 KB" data-testid="blob-size" class="Truncate__StyledTruncate-sc-23o1d2-0 eAtkQz"><span>2080 lines (1682 loc) · 105 KB</span></div></div></div></div><div class="Box-sc-g0xbh4-0 kcLCKF"><div class="Box-sc-g0xbh4-0 kVWtTz react-blob-header-edit-and-raw-actions"><div class="Box-sc-g0xbh4-0 prc-ButtonGroup-ButtonGroup-vcMeG"><div><a href="https://github.com/kubernetes/community/raw/refs/heads/master/contributors/devel/sig-architecture/api-conventions.md" data-testid="raw-button" class="Box-sc-g0xbh4-0 gWqxTd prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":R5csptal9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Raw</span></span></a></div><div><button data-component="IconButton" type="button" aria-label="Copy raw content" data-testid="copy-raw-button" class="prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":Rpcsptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button></div><div><span role="tooltip" aria-label="Download raw file" id=":Rdcsptal9lab:" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-n"><button data-component="IconButton" type="button" aria-label="Download raw content" data-testid="download-raw-button" class="Box-sc-g0xbh4-0 ivobqY prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":Rtcsptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button></span></div></div><button hidden="" data-testid="raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="copy-raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="download-raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button></div><button data-component="IconButton" type="button" aria-label="Outline" aria-pressed="false" class="Box-sc-g0xbh4-0 iNRSob prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":R6sptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" aria-label="Edit and raw actions" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 ffkqe prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":Rnsptal9lab:-loading-announcement" id=":Rnsptal9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button></div></div></div></div><div></div></div><div class="Box-sc-g0xbh4-0 hGyMdv"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="Box-sc-g0xbh4-0 fGqKFv"><div class="Box-sc-g0xbh4-0 eoaCFS js-snippet-clipboard-copy-unpositioned undefined" data-hpc="true"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">API Conventions</h1><a id="user-content-api-conventions" class="anchor" aria-label="Permalink: API Conventions" href="#api-conventions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><em>This document is oriented at users who want a deeper understanding of the Kubernetes API structure, and developers wanting to extend the Kubernetes API. An introduction to using resources with kubectl can be found in <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/" rel="nofollow">the object management overview</a>.</em></p> <p dir="auto"><strong>Table of Contents</strong></p> <ul dir="auto"> <li><a href="#types-kinds">Types (Kinds)</a> <ul dir="auto"> <li><a href="#resources">Resources</a></li> <li><a href="#objects">Objects</a> <ul dir="auto"> <li><a href="#metadata">Metadata</a></li> <li><a href="#spec-and-status">Spec and Status</a> <ul dir="auto"> <li><a href="#typical-status-properties">Typical status properties</a></li> </ul> </li> <li><a href="#references-to-related-objects">References to related objects</a></li> <li><a href="#lists-of-named-subobjects-preferred-over-maps">Lists of named subobjects preferred over maps</a></li> <li><a href="#primitive-types">Primitive types</a></li> <li><a href="#constants">Constants</a></li> <li><a href="#unions">Unions</a></li> </ul> </li> <li><a href="#lists-and-simple-kinds">Lists and Simple kinds</a></li> </ul> </li> <li><a href="#differing-representations">Differing Representations</a></li> <li><a href="#verbs-on-resources">Verbs on Resources</a> <ul dir="auto"> <li><a href="#patch-operations">PATCH operations</a></li> </ul> </li> <li><a href="#short-names-and-categories">Short-names and Categories</a> <ul dir="auto"> <li><a href="#short-names">Short-names</a></li> <li><a href="#categories">Categories</a></li> </ul> </li> <li><a href="#idempotency">Idempotency</a></li> <li><a href="#optional-vs-required">Optional vs. Required</a></li> <li><a href="#defaulting">Defaulting</a> <ul dir="auto"> <li><a href="#static-defaults">Static Defaults</a></li> <li><a href="#admission-controlled-defaults">Admission Controlled Defaults</a></li> <li><a href="#controller-assigned-defaults-aka-late-initialization">Controller-Assigned Defaults (aka Late Initialization)</a></li> <li><a href="#what-may-be-defaulted">What May Be Defaulted</a></li> <li><a href="#considerations-for-put-operations">Considerations For PUT Operations</a></li> </ul> </li> <li><a href="#concurrency-control-and-consistency">Concurrency Control and Consistency</a></li> <li><a href="#serialization-format">Serialization Format</a></li> <li><a href="#units">Units</a></li> <li><a href="#selecting-fields">Selecting Fields</a></li> <li><a href="#object-references">Object references</a> <ul dir="auto"> <li><a href="#naming-of-the-reference-field">Naming of the reference field</a></li> <li><a href="#referencing-resources-with-multiple-versions">Referencing resources with multiple versions</a></li> <li><a href="#handling-of-resources-that-do-not-exist">Handling of resources that do not exist</a></li> <li><a href="#validation-of-fields">Validation of fields</a></li> <li><a href="#do-not-modify-the-referred-object">Do not modify the referred object</a></li> <li><a href="#minimize-copying-or-printing-values-to-the-referrer-object">Minimize copying or printing values to the referrer object</a></li> <li><a href="#object-references-examples">Object References Examples</a> <ul dir="auto"> <li><a href="#single-resource-reference">Single resource reference</a> <ul dir="auto"> <li><a href="#controller-behavior">Controller behavior</a></li> </ul> </li> <li><a href="#multiple-resource-reference">Multiple resource reference</a> <ul dir="auto"> <li><a href="#kind-vs-resource">Kind vs. Resource</a></li> <li><a href="#controller-behavior-1">Controller behavior</a></li> </ul> </li> <li><a href="#generic-object-reference">Generic object reference</a> <ul dir="auto"> <li><a href="#controller-behavior-2">Controller behavior</a></li> </ul> </li> <li><a href="#field-reference">Field reference</a> <ul dir="auto"> <li><a href="#controller-behavior-3">Controller behavior</a></li> </ul> </li> </ul> </li> </ul> </li> <li><a href="#http-status-codes">HTTP Status codes</a> <ul dir="auto"> <li><a href="#success-codes">Success codes</a></li> <li><a href="#error-codes">Error codes</a></li> </ul> </li> <li><a href="#response-status-kind">Response Status Kind</a></li> <li><a href="#events">Events</a></li> <li><a href="#naming-conventions">Naming conventions</a> <ul dir="auto"> <li><a href="#namespace-names">Namespace Names</a></li> </ul> </li> <li><a href="#label-selector-and-annotation-conventions">Label, selector, and annotation conventions</a></li> <li><a href="#websockets-and-spdy">WebSockets and SPDY</a></li> <li><a href="#validation">Validation</a></li> <li><a href="#automatic-resource-allocation-and-deallocation">Automatic Resource Allocation And Deallocation</a></li> <li><a href="#representing-allocated-values">Representing Allocated Values</a> <ul dir="auto"> <li><a href="#when-to-use-a-spec-field">When to use a <code>spec</code> field</a></li> <li><a href="#when-to-use-a-status-field">When to use a <code>status</code> field</a> <ul dir="auto"> <li><a href="#sequencing-operations">Sequencing operations</a></li> </ul> </li> <li><a href="#when-to-use-a-different-type">When to use a different type</a></li> </ul> </li> </ul> <p dir="auto">The conventions of the <a href="https://kubernetes.io/docs/concepts/overview/kubernetes-api/" rel="nofollow">Kubernetes API</a> (and related APIs in the ecosystem) are intended to ease client development and ensure that configuration mechanisms can be implemented that work across a diverse set of use cases consistently.</p> <p dir="auto">The general style of the Kubernetes API is RESTful - clients create, update, delete, or retrieve a description of an object via the standard HTTP verbs (POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return JSON. Kubernetes also exposes additional endpoints for non-standard verbs and allows alternative content types. All of the JSON accepted and returned by the server has a schema, identified by the "kind" and "apiVersion" fields. Where relevant HTTP header fields exist, they should mirror the content of JSON fields, but the information should not be represented only in the HTTP header.</p> <p dir="auto">The following terms are defined:</p> <ul dir="auto"> <li><strong>Kind</strong> the name of a particular object schema (e.g. the "Cat" and "Dog" kinds would have different attributes and properties)</li> <li><strong>Resource</strong> a representation of a system entity, sent or retrieved as JSON via HTTP to the server. Resources are exposed via: <ul dir="auto"> <li>Collections - a list of resources of the same type, which may be queryable</li> <li>Elements - an individual resource, addressable via a URL</li> </ul> </li> <li><strong>API Group</strong> a set of resources that are exposed together, along with the version exposed in the "apiVersion" field as "GROUP/VERSION", e.g. "policy.k8s.io/v1".</li> </ul> <p dir="auto">Each resource typically accepts and returns data of a single kind. A kind may be accepted or returned by multiple resources that reflect specific use cases. For instance, the kind "Pod" is exposed as a "pods" resource that allows end users to create, update, and delete pods, while a separate "pod status" resource (that acts on "Pod" kind) allows automated processes to update a subset of the fields in that resource.</p> <p dir="auto">Resources are bound together in API groups - each group may have one or more versions that evolve independent of other API groups, and each version within the group has one or more resources. Group names are typically in domain name form - the Kubernetes project reserves use of the empty group, all single word names ("extensions", "apps"), and any group name ending in "*.k8s.io" for its sole use. When choosing a group name, we recommend selecting a subdomain your group or organization owns, such as "widget.mycompany.com".</p> <p dir="auto">Version strings should match <a href="https://git.k8s.io/design-proposals-archive/architecture/identifiers.md" rel="nofollow">DNS_LABEL</a> format.</p> <p dir="auto">Resource collections should be all lowercase and plural, whereas kinds are CamelCase and singular. Group names must be lower case and be valid DNS subdomains.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Types (Kinds)</h2><a id="user-content-types-kinds" class="anchor" aria-label="Permalink: Types (Kinds)" href="#types-kinds"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Kinds are grouped into three categories:</p> <ol dir="auto"> <li> <p dir="auto"><strong>Objects</strong> represent a persistent entity in the system.</p> <p dir="auto">Creating an API object is a record of intent - once created, the system will work to ensure that resource exists. All API objects have common metadata.</p> <p dir="auto">An object may have multiple resources that clients can use to perform specific actions that create, update, delete, or get.</p> <p dir="auto">Examples: <code>Pod</code>, <code>ReplicationController</code>, <code>Service</code>, <code>Namespace</code>, <code>Node</code>.</p> </li> <li> <p dir="auto"><strong>Lists</strong> are collections of <strong>resources</strong> of one (usually) or more (occasionally) kinds.</p> <p dir="auto">The name of a list kind must end with "List". Lists have a limited set of common metadata. All lists use the required "items" field to contain the array of objects they return. Any kind that has the "items" field must be a list kind.</p> <p dir="auto">Most objects defined in the system should have an endpoint that returns the full set of resources, as well as zero or more endpoints that return subsets of the full list. Some objects may be singletons (the current user, the system defaults) and may not have lists.</p> <p dir="auto">In addition, all lists that return objects with labels should support label filtering (see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/" rel="nofollow">the labels documentation</a>), and most lists should support filtering by fields (see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/" rel="nofollow">the fields documentation</a>).</p> <p dir="auto">Examples: <code>PodList</code>, <code>ServiceList</code>, <code>NodeList</code>.</p> </li> </ol> <p dir="auto">Note that<code>kubectl</code> and other tools sometimes output collections of resources as <code>kind: List</code>. Keep in mind that <code>kind: List</code> is not part of the Kubernetes API; it is exposing an implementation detail from client-side code in those tools, used to handle groups of mixed resources.</p> <ol start="3" dir="auto"> <li> <p dir="auto"><strong>Simple</strong> kinds are used for specific actions on objects and for non-persistent entities.</p> <p dir="auto">Given their limited scope, they have the same set of limited common metadata as lists.</p> <p dir="auto">For instance, the "Status" kind is returned when errors occur and is not persisted in the system.</p> <p dir="auto">Many simple resources are "subresources", which are rooted at API paths of specific resources. When resources wish to expose alternative actions or views that are closely coupled to a single resource, they should do so using new sub-resources. Common subresources include:</p> <ul dir="auto"> <li><code>/binding</code>: Used to bind a resource representing a user request (e.g., Pod, PersistentVolumeClaim) to a cluster infrastructure resource (e.g., Node, PersistentVolume).</li> <li><code>/status</code>: Used to write just the <code>status</code> portion of a resource. For example, the <code>/pods</code> endpoint only allows updates to <code>metadata</code> and <code>spec</code>, since those reflect end-user intent. An automated process should be able to modify status for users to see by sending an updated Pod kind to the server to the "/pods/&lt;name&gt;/status" endpoint - the alternate endpoint allows different rules to be applied to the update, and access to be appropriately restricted.</li> <li><code>/scale</code>: Used to read and write the count of a resource in a manner that is independent of the specific resource schema.</li> </ul> <p dir="auto">Two additional subresources, <code>proxy</code> and <code>portforward</code>, provide access to cluster resources as described in <a href="https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/" rel="nofollow">accessing the cluster</a>.</p> </li> </ol> <p dir="auto">The standard REST verbs (defined below) MUST return singular JSON objects. Some API endpoints may deviate from the strict REST pattern and return resources that are not singular JSON objects, such as streams of JSON objects or unstructured text log data.</p> <p dir="auto">A common set of "meta" API objects are used across all API groups and are thus considered part of the API group named <code>meta.k8s.io</code>. These types may evolve independent of the API group that uses them and API servers may allow them to be addressed in their generic form. Examples are <code>ListOptions</code>, <code>DeleteOptions</code>, <code>List</code>, <code>Status</code>, <code>WatchEvent</code>, and <code>Scale</code>. For historical reasons these types are part of each existing API group. Generic tools like quota, garbage collection, autoscalers, and generic clients like kubectl leverage these types to define consistent behavior across different resource types, like the interfaces in programming languages.</p> <p dir="auto">The term "kind" is reserved for these "top-level" API types. The term "type" should be used for distinguishing sub-categories within objects or subobjects.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Resources</h3><a id="user-content-resources" class="anchor" aria-label="Permalink: Resources" href="#resources"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">All JSON objects returned by an API MUST have the following fields:</p> <ul dir="auto"> <li>kind: a string that identifies the schema this object should have</li> <li>apiVersion: a string that identifies the version of the schema the object should have</li> </ul> <p dir="auto">These fields are required for proper decoding of the object. They may be populated by the server by default from the specified URL path, but the client likely needs to know the values in order to construct the URL path.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Objects</h3><a id="user-content-objects" class="anchor" aria-label="Permalink: Objects" href="#objects"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Metadata</h4><a id="user-content-metadata" class="anchor" aria-label="Permalink: Metadata" href="#metadata"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Every object kind MUST have the following metadata in a nested object field called "metadata":</p> <ul dir="auto"> <li>namespace: a namespace is a DNS compatible label that objects are subdivided into. The default namespace is 'default'. See <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/" rel="nofollow">the namespace docs</a> for more.</li> <li>name: a string that uniquely identifies this object within the current namespace (see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/names/" rel="nofollow">the identifiers docs</a>). This value is used in the path when retrieving an individual object.</li> <li>uid: a unique in time and space value (typically an RFC 4122 generated identifier, see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/names/" rel="nofollow">the identifiers docs</a>) used to distinguish between objects with the same name that have been deleted and recreated</li> </ul> <p dir="auto">Every object SHOULD have the following metadata in a nested object field called "metadata":</p> <ul dir="auto"> <li>resourceVersion: a string that identifies the internal version of this object that can be used by clients to determine when objects have changed. This value MUST be treated as opaque by clients and passed unmodified back to the server. Clients should not assume that the resource version has meaning across namespaces, different kinds of resources, or different servers. (See <a href="#concurrency-control-and-consistency">concurrency control</a>, below, for more details.)</li> <li>generation: a sequence number representing a specific generation of the desired state. Set by the system and monotonically increasing, per-resource. May be compared, such as for RAW and WAW consistency.</li> <li>creationTimestamp: a string representing an RFC 3339 date of the date and time an object was created</li> <li>deletionTimestamp: a string representing an RFC 3339 date of the date and time after which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource will be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field except when the object has a finalizer set. In case the finalizer is set the deletion of the object is postponed at least until the finalizer is removed. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time.</li> <li>labels: a map of string keys and values that can be used to organize and categorize objects (see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/" rel="nofollow">the labels docs</a>)</li> <li>annotations: a map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about this object (see <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/" rel="nofollow">the annotations docs</a>)</li> </ul> <p dir="auto">Labels are intended for organizational purposes by end users (select the pods that match this label query). Annotations enable third-party automation and tooling to decorate objects with additional metadata for their own use.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Spec and Status</h4><a id="user-content-spec-and-status" class="anchor" aria-label="Permalink: Spec and Status" href="#spec-and-status"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">By convention, the Kubernetes API makes a distinction between the specification of the desired state of an object (a nested object field called <code>spec</code>) and the status of the object at the current time (a nested object field called <code>status</code>). The specification is a complete description of the desired state, including configuration settings provided by the user, <a href="#defaulting">default values</a> expanded by the system, and properties initialized or otherwise changed after creation by other ecosystem components (e.g., schedulers, auto-scalers), and is persisted in stable storage with the API object. If the specification is deleted, the object will be purged from the system.</p> <p dir="auto">The <code>status</code> summarizes the current state of the object in the system, and is usually persisted with the object by automated processes but may be generated on the fly. As a general guideline, fields in <code>status</code> should be the most recent observations of actual state, but they may contain information such as the results of allocations or similar operations which are executed in response to the object's <code>spec</code>. See <a href="#representing-allocated-values">below</a> for more details.</p> <p dir="auto">Types with both <code>spec</code> and <code>status</code> stanzas can (and usually should) have distinct authorization scopes for them. This allows users to be granted full write access to <code>spec</code> and read-only access to status, while relevant controllers are granted read-only access to <code>spec</code> but full write access to status.</p> <p dir="auto">When a new version of an object is POSTed or PUT, the <code>spec</code> is updated and available immediately. Over time the system will work to bring the <code>status</code> into line with the <code>spec</code>. The system will drive toward the most recent <code>spec</code> regardless of previous versions of that stanza. For example, if a value is changed from 2 to 5 in one PUT and then back down to 3 in another PUT the system is not required to 'touch base' at 5 before changing the <code>status</code> to 3. In other words, the system's behavior is <em>level-based</em> rather than <em>edge-based</em>. This enables robust behavior in the presence of missed intermediate state changes.</p> <p dir="auto">The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. In order to facilitate level-based operation and expression of declarative configuration, fields in the specification should have declarative rather than imperative names and semantics -- they represent the desired state, not actions intended to yield the desired state.</p> <p dir="auto">The PUT and POST verbs on objects MUST ignore the <code>status</code> values, to avoid accidentally overwriting the <code>status</code> in read-modify-write scenarios. A <code>/status</code> subresource MUST be provided to enable system components to update statuses of resources they manage.</p> <p dir="auto">Otherwise, PUT expects the whole object to be specified. Therefore, if a field is omitted it is assumed that the client wants to clear that field's value. The PUT verb does not accept partial updates. Modification of just part of an object may be achieved by GETting the resource, modifying part of the spec, labels, or annotations, and then PUTting it back. See <a href="#concurrency-control-and-consistency">concurrency control</a>, below, regarding read-modify-write consistency when using this pattern. Some objects may expose alternative resource representations that allow mutation of the status, or performing custom actions on the object.</p> <p dir="auto">All objects that represent a physical resource whose state may vary from the user's desired intent SHOULD have a <code>spec</code> and a <code>status</code>. Objects whose state cannot vary from the user's desired intent MAY have only <code>spec</code>, and MAY rename <code>spec</code> to a more appropriate name.</p> <p dir="auto">Objects that contain both <code>spec</code> and <code>status</code> should not contain additional top-level fields other than the standard metadata fields.</p> <p dir="auto">Some objects which are not persisted in the system - such as <code>SubjectAccessReview</code> and other webhook style calls - may choose to add <code>spec</code> and <code>status</code> to encapsulate a "call and response" pattern. The <code>spec</code> is the request (often a request for information) and the <code>status</code> is the response. For these RPC like objects the only operation may be POST, but having a consistent schema between submission and response reduces the complexity of these clients.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Typical status properties</h5><a id="user-content-typical-status-properties" class="anchor" aria-label="Permalink: Typical status properties" href="#typical-status-properties"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><strong>Conditions</strong> provide a standard mechanism for higher-level status reporting from a controller. They are an extension mechanism which allows tools and other controllers to collect summary information about resources without needing to understand resource-specific status details. Conditions should complement more detailed information about the observed status of an object written by a controller, rather than replace it. For example, the "Available" condition of a Deployment can be determined by examining <code>readyReplicas</code>, <code>replicas</code>, and other properties of the Deployment. However, the "Available" condition allows other components to avoid duplicating the availability logic in the Deployment controller.</p> <p dir="auto">Objects may report multiple conditions, and new types of conditions may be added in the future or by 3rd party controllers. Therefore, conditions are represented using a list/slice of objects, where each condition has a similar structure. This collection should be treated as a map with a key of <code>type</code>.</p> <p dir="auto">Conditions are most useful when they follow some consistent conventions:</p> <ul dir="auto"> <li> <p dir="auto">Conditions should be added to explicitly convey properties that users and components care about rather than requiring those properties to be inferred from other observations. Once defined, the meaning of a Condition can not be changed arbitrarily - it becomes part of the API, and has the same backwards- and forwards-compatibility concerns of any other part of the API.</p> </li> <li> <p dir="auto">Controllers should apply their conditions to a resource the first time they visit the resource, even if the <code>status</code> is Unknown. This allows other components in the system to know that the condition exists and the controller is making progress on reconciling that resource.</p> <ul dir="auto"> <li>Not all controllers will observe the previous advice about reporting "Unknown" or "False" values. For known conditions, the absence of a condition <code>status</code> should be interpreted the same as <code>Unknown</code>, and typically indicates that reconciliation has not yet finished (or that the resource state may not yet be observable).</li> </ul> </li> <li> <p dir="auto">For some conditions, <code>True</code> represents normal operation, and for some conditions, <code>False</code> represents normal operation. ("Normal-true" conditions are sometimes said to have "positive polarity", and "normal-false" conditions are said to have "negative polarity".) Without further knowledge of the conditions, it is not possible to compute a generic summary of the conditions on a resource.</p> </li> <li> <p dir="auto">Condition type names should make sense for humans; neither positive nor negative polarity can be recommended as a general rule. A negative condition like "MemoryExhausted" may be easier for humans to understand than "SufficientMemory". Conversely, "Ready" or "Succeeded" may be easier to understand than "Failed", because "Failed=Unknown" or "Failed=False" may cause double-negative confusion.</p> </li> <li> <p dir="auto">Condition type names should describe the current observed state of the resource, rather than describing the current state transitions. This typically means that the name should be an adjective ("Ready", "OutOfDisk") or a past-tense verb ("Succeeded", "Failed") rather than a present-tense verb ("Deploying"). Intermediate states may be indicated by setting the <code>status</code> of the condition to <code>Unknown</code>.</p> <ul dir="auto"> <li>For state transitions which take a long period of time (e.g. more than 1 minute), it is reasonable to treat the transition itself as an observed state. In these cases, the Condition (such as "Resizing") itself should not be transient, and should instead be signalled using the <code>True</code>/<code>False</code>/<code>Unknown</code> pattern. This allows other observers to determine the last update from the controller, whether successful or failed. In cases where the state transition is unable to complete and continued reconciliation is not feasible, the Reason and Message should be used to indicate that the transition failed.</li> </ul> </li> <li> <p dir="auto">When designing Conditions for a resource, it's helpful to have a common top-level condition which summarizes more detailed conditions. Simple consumers may simply query the top-level condition. Although they are not a consistent standard, the <code>Ready</code> and <code>Succeeded</code> condition types may be used by API designers for long-running and bounded-execution objects, respectively.</p> </li> </ul> <p dir="auto">Conditions should follow the standard schema included in <a href="https://github.com/kubernetes/apimachinery/blob/release-1.23/pkg/apis/meta/v1/types.go#L1432-L1492">k8s.io/apimachinery/pkg/apis/meta/v1/types.go</a>. It should be included as a top level element in status, similar to</p> <div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// +listType=map // +listMapKey=type // +patchStrategy=merge // +patchMergeKey=type // +optional Conditions []metav1.Condition `json:&quot;conditions,omitempty&quot; patchStrategy:&quot;merge&quot; patchMergeKey:&quot;type&quot; protobuf:&quot;bytes,1,rep,name=conditions&quot;`"><pre><span class="pl-c">// +listType=map</span> <span class="pl-c">// +listMapKey=type</span> <span class="pl-c">// +patchStrategy=merge</span> <span class="pl-c">// +patchMergeKey=type</span> <span class="pl-c">// +optional</span> <span class="pl-s1">Conditions</span> []metav1.<span class="pl-smi">Condition</span> <span class="pl-s">`json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`</span></pre></div> <p dir="auto">The <code>metav1.Conditions</code> includes the following fields</p> <div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// type of condition in CamelCase or in foo.example.com/CamelCase. // +required Type string `json:&quot;type&quot; protobuf:&quot;bytes,1,opt,name=type&quot;` // status of the condition, one of True, False, Unknown. // +required Status ConditionStatus `json:&quot;status&quot; protobuf:&quot;bytes,2,opt,name=status&quot;` // observedGeneration represents the .metadata.generation that the condition was set based upon. // For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date // with respect to the current state of the instance. // +optional ObservedGeneration int64 `json:&quot;observedGeneration,omitempty&quot; protobuf:&quot;varint,3,opt,name=observedGeneration&quot;` // lastTransitionTime is the last time the condition transitioned from one status to another. // This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. // +required LastTransitionTime Time `json:&quot;lastTransitionTime&quot; protobuf:&quot;bytes,4,opt,name=lastTransitionTime&quot;` // reason contains a programmatic identifier indicating the reason for the condition's last transition. // Producers of specific condition types may define expected values and meanings for this field, // and whether the values are considered a guaranteed API. // The value should be a CamelCase string. // This field may not be empty. // +required Reason string `json:&quot;reason&quot; protobuf:&quot;bytes,5,opt,name=reason&quot;` // message is a human readable message indicating details about the transition. // This may be an empty string. // +required Message string `json:&quot;message&quot; protobuf:&quot;bytes,6,opt,name=message&quot;`"><pre><span class="pl-c">// type of condition in CamelCase or in foo.example.com/CamelCase.</span> <span class="pl-c">// +required</span> <span class="pl-s1">Type</span> <span class="pl-s1">string</span> <span class="pl-s">`json:"type" protobuf:"bytes,1,opt,name=type"`</span> <span class="pl-c">// status of the condition, one of True, False, Unknown.</span> <span class="pl-c">// +required</span> <span class="pl-s1">Status</span> <span class="pl-s1">ConditionStatus</span> <span class="pl-s">`json:"status" protobuf:"bytes,2,opt,name=status"`</span> <span class="pl-c">// observedGeneration represents the .metadata.generation that the condition was set based upon.</span> <span class="pl-c">// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date</span> <span class="pl-c">// with respect to the current state of the instance.</span> <span class="pl-c">// +optional</span> <span class="pl-s1">ObservedGeneration</span> <span class="pl-s1">int64</span> <span class="pl-s">`json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`</span> <span class="pl-c">// lastTransitionTime is the last time the condition transitioned from one status to another.</span> <span class="pl-c">// This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.</span> <span class="pl-c">// +required</span> <span class="pl-s1">LastTransitionTime</span> <span class="pl-s1">Time</span> <span class="pl-s">`json:"lastTransitionTime" protobuf:"bytes,4,opt,name=lastTransitionTime"`</span> <span class="pl-c">// reason contains a programmatic identifier indicating the reason for the condition's last transition.</span> <span class="pl-c">// Producers of specific condition types may define expected values and meanings for this field,</span> <span class="pl-c">// and whether the values are considered a guaranteed API.</span> <span class="pl-c">// The value should be a CamelCase string.</span> <span class="pl-c">// This field may not be empty.</span> <span class="pl-c">// +required</span> <span class="pl-s1">Reason</span> <span class="pl-s1">string</span> <span class="pl-s">`json:"reason" protobuf:"bytes,5,opt,name=reason"`</span> <span class="pl-c">// message is a human readable message indicating details about the transition.</span> <span class="pl-c">// This may be an empty string.</span> <span class="pl-c">// +required</span> <span class="pl-s1">Message</span> <span class="pl-s1">string</span> <span class="pl-s">`json:"message" protobuf:"bytes,6,opt,name=message"`</span></pre></div> <p dir="auto">Additional fields may be added in the future.</p> <p dir="auto">Use of the <code>Reason</code> field is required.</p> <p dir="auto">Condition types should be named in PascalCase. Short condition names are preferred (e.g. "Ready" over "MyResourceReady").</p> <p dir="auto">Condition <code>status</code> values may be <code>True</code>, <code>False</code>, or <code>Unknown</code>. The absence of a condition should be interpreted the same as <code>Unknown</code>. How controllers handle <code>Unknown</code> depends on the Condition in question.</p> <p dir="auto">The thinking around conditions has evolved over time, so there are several non-normative examples in wide use.</p> <p dir="auto">In general, condition values may change back and forth, but some condition transitions may be monotonic, depending on the resource and condition type. However, conditions are observations and not, themselves, state machines, nor do we define comprehensive state machines for objects, nor behaviors associated with state transitions. The system is level-based rather than edge-triggered, and should assume an Open World.</p> <p dir="auto">An example of an oscillating condition type is <code>Ready</code>, which indicates the object was believed to be fully operational at the time it was last probed. A possible monotonic condition could be <code>Succeeded</code>. A <code>True</code> status for <code>Succeeded</code> would imply completion and that the resource was no longer active. An object that was still active would generally have a <code>Succeeded</code> condition with status <code>Unknown</code>.</p> <p dir="auto">Some resources in the v1 API contain fields called <strong><code>phase</code></strong>, and associated <code>message</code>, <code>reason</code>, and other status fields. The pattern of using <code>phase</code> is deprecated. Newer API types should use conditions instead. Phase was essentially a state-machine enumeration field, that contradicted <a href="https://git.k8s.io/design-proposals-archive/architecture/principles.md#control-logic" rel="nofollow">system-design principles</a> and hampered evolution, since <a href="/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md">adding new enum values breaks backward compatibility</a>. Rather than encouraging clients to infer implicit properties from phases, we prefer to explicitly expose the individual conditions that clients need to monitor. Conditions also have the benefit that it is possible to create some conditions with uniform meaning across all resource types, while still exposing others that are unique to specific resource types. See <a href="http://issues.k8s.io/7856" rel="nofollow">#7856</a> for more details and discussion.</p> <p dir="auto">In condition types, and everywhere else they appear in the API, <strong><code>Reason</code></strong> is intended to be a one-word, CamelCase representation of the category of cause of the current status, and <strong><code>Message</code></strong> is intended to be a human-readable phrase or sentence, which may contain specific details of the individual occurrence. <code>Reason</code> is intended to be used in concise output, such as one-line <code>kubectl get</code> output, and in summarizing occurrences of causes, whereas <code>Message</code> is intended to be presented to users in detailed status explanations, such as <code>kubectl describe</code> output.</p> <p dir="auto">Historical information status (e.g., last transition time, failure counts) is only provided with reasonable effort, and is not guaranteed to not be lost.</p> <p dir="auto">Status information that may be large (especially proportional in size to collections of other resources, such as lists of references to other objects -- see below) and/or rapidly changing, such as <a href="https://git.k8s.io/design-proposals-archive/scheduling/resources.md#usage-data" rel="nofollow">resource usage</a>, should be put into separate objects, with possibly a reference from the original object. This helps to ensure that GETs and watch remain reasonably efficient for the majority of clients, which may not need that data.</p> <p dir="auto">Some resources report the <code>observedGeneration</code>, which is the <code>generation</code> most recently observed by the component responsible for acting upon changes to the desired state of the resource. This can be used, for instance, to ensure that the reported status reflects the most recent desired status.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">References to related objects</h4><a id="user-content-references-to-related-objects" class="anchor" aria-label="Permalink: References to related objects" href="#references-to-related-objects"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">References to loosely coupled sets of objects, such as <a href="https://kubernetes.io/docs/concepts/workloads/pods/" rel="nofollow">pods</a> overseen by a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/" rel="nofollow">replication controller</a>, are usually best referred to using a <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors" rel="nofollow">label selector</a>. In order to ensure that GETs of individual objects remain bounded in time and space, these sets may be queried via separate API queries, but will not be expanded in the referring object's status.</p> <p dir="auto">For references to specific objects, see <a href="#object-references">Object references</a>.</p> <p dir="auto">References in the <code>status</code> of the referee to the referrer may be permitted, when the references are one-to-one and do not need to be frequently updated, particularly in an edge-based manner.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Lists of named subobjects preferred over maps</h4><a id="user-content-lists-of-named-subobjects-preferred-over-maps" class="anchor" aria-label="Permalink: Lists of named subobjects preferred over maps" href="#lists-of-named-subobjects-preferred-over-maps"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Discussed in <a href="http://issue.k8s.io/2004" rel="nofollow">#2004</a> and elsewhere. There are no maps of subobjects in any API objects. Instead, the convention is to use a list of subobjects containing name fields. These conventions, and how one can change the semantics of lists, structs and maps are described in more details in the Kubernetes <a href="https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy" rel="nofollow">documentation</a>.</p> <p dir="auto">For example:</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="ports: - name: www containerPort: 80"><pre><span class="pl-ent">ports</span>: - <span class="pl-ent">name</span>: <span class="pl-s">www</span> <span class="pl-ent">containerPort</span>: <span class="pl-c1">80</span></pre></div> <p dir="auto">vs.</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="ports: www: containerPort: 80"><pre><span class="pl-ent">ports</span>: <span class="pl-ent">www</span>: <span class="pl-ent">containerPort</span>: <span class="pl-c1">80</span></pre></div> <p dir="auto">This rule maintains the invariant that all JSON/YAML keys are fields in API objects. The only exceptions are pure maps in the API (currently, labels, selectors, annotations, data), as opposed to sets of subobjects.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Primitive types</h4><a id="user-content-primitive-types" class="anchor" aria-label="Permalink: Primitive types" href="#primitive-types"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>Look at similar fields in the API (e.g. ports, durations) and follow the conventions of existing fields.</li> <li>Do not use enums. Use aliases for string instead (e.g. <code>NodeConditionType</code>).</li> <li>All numeric fields should be bounds-checked, both for too-small or negative and for too-large.</li> <li>All public integer fields MUST use the Go <code>int32</code> or Go <code>int64</code> types, not <code>int</code> (which is ambiguously sized, depending on target platform). Internal types may use <code>int</code>.</li> <li>For integer fields, prefer <code>int32</code> to <code>int64</code> unless you need to represent values larger than <code>int32</code>. See other guidelines about limitations of <code>int64</code> and language compatibility.</li> <li>Do not use unsigned integers, due to inconsistent support across languages and libraries. Just validate that the integer is non-negative if that's the case.</li> <li>All numbers (e.g. <code>int32</code>, <code>int64</code>) are converted to <code>float64</code> by Javascript and some other languages, so any field which is expected to exceed that either in magnitude or in precision (e.g. integer values &gt; 53 bits) should be serialized and accepted as strings. <code>int64</code> fields must be bounds-checked to be within the range of <code>-(2^53) &lt; x &lt; (2^53)</code>.</li> <li>Avoid floating-point values as much as possible, and never use them in spec. Floating-point values cannot be reliably round-tripped (encoded and re-decoded) without changing, and have varying precision and representations across languages and architectures.</li> <li>Think twice about <code>bool</code> fields. Many ideas start as boolean but eventually trend towards a small set of mutually exclusive options. Plan for future expansions by describing the policy options explicitly as a string type alias (e.g. <code>TerminationMessagePolicy</code>).</li> </ul> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Constants</h4><a id="user-content-constants" class="anchor" aria-label="Permalink: Constants" href="#constants"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: <code>ClusterFirst</code>, <code>Pending</code>, <code>ClientIP</code>. When an acronym or initialism each letter in the acronym should be uppercase, such as with <code>ClientIP</code> or <code>TCPDelay</code>. When a proper name or the name of a command-line executable is used as a constant the proper name should be represented in consistent casing - examples: <code>systemd</code>, <code>iptables</code>, <code>IPVS</code>, <code>cgroupfs</code>, <code>Docker</code> (as a generic concept), <code>docker</code> (as the command-line executable). If a proper name is used which has mixed capitalization like <code>eBPF</code> that should be preserved in a longer constant such as <code>eBPFDelegation</code>.</p> <p dir="auto">All API within Kubernetes must leverage constants in this style, including flags and configuration files. Where inconsistent constants were previously used, new flags should be CamelCase only, and over time old flags should be updated to accept a CamelCase value alongside the inconsistent constant. Example: the Kubelet accepts a <code>--topology-manager-policy</code> flag that has values <code>none</code>, <code>best-effort</code>, <code>restricted</code>, and <code>single-numa-node</code>. This flag should accept <code>None</code>, <code>BestEffort</code>, <code>Restricted</code>, and <code>SingleNUMANode</code> going forward. If new values are added to the flag, both forms should be supported.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Unions</h4><a id="user-content-unions" class="anchor" aria-label="Permalink: Unions" href="#unions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Sometimes, at most one of a set of fields can be set. For example, the [volumes] field of a PodSpec has 17 different volume type-specific fields, such as <code>nfs</code> and <code>iscsi</code>. All fields in the set should be <a href="#optional-vs-required">Optional</a>.</p> <p dir="auto">Sometimes, when a new type is created, the api designer may anticipate that a union will be needed in the future, even if only one field is allowed initially. In this case, be sure to make the field <a href="#optional-vs-required">Optional</a> In the validation, you may still return an error if the sole field is unset. Do not set a default value for that field.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Lists and Simple kinds</h3><a id="user-content-lists-and-simple-kinds" class="anchor" aria-label="Permalink: Lists and Simple kinds" href="#lists-and-simple-kinds"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Every list or simple kind SHOULD have the following metadata in a nested object field called "metadata":</p> <ul dir="auto"> <li>resourceVersion: a string that identifies the common version of the objects returned by in a list. This value MUST be treated as opaque by clients and passed unmodified back to the server. A resource version is only valid within a single namespace on a single kind of resource.</li> </ul> <p dir="auto">Every simple kind returned by the server, and any simple kind sent to the server that must support idempotency or optimistic concurrency should return this value. Since simple resources are often used as input alternate actions that modify objects, the resource version of the simple resource should correspond to the resource version of the object.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Differing Representations</h2><a id="user-content-differing-representations" class="anchor" aria-label="Permalink: Differing Representations" href="#differing-representations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">An API may represent a single entity in different ways for different clients, or transform an object after certain transitions in the system occur. In these cases, one request object may have two representations available as different resources, or different kinds.</p> <p dir="auto">An example is a Service, which represents the intent of the user to group a set of pods with common behavior on common ports. When Kubernetes detects a pod matches the service selector, the IP address and port of the pod are added to an Endpoints resource for that Service. The Endpoints resource exists only if the Service exists, but exposes only the IPs and ports of the selected pods. The full service is represented by two distinct resources - under the original Service resource the user created, as well as in the Endpoints resource.</p> <p dir="auto">As another example, a "pod status" resource may accept a PUT with the "pod" kind, with different rules about what fields may be changed.</p> <p dir="auto">Future versions of Kubernetes may allow alternative encodings of objects beyond JSON.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Verbs on Resources</h2><a id="user-content-verbs-on-resources" class="anchor" aria-label="Permalink: Verbs on Resources" href="#verbs-on-resources"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">API resources should use the traditional REST pattern:</p> <ul dir="auto"> <li>GET /&lt;resourceNamePlural&gt; - Retrieve a list of type &lt;resourceName&gt;, e.g. GET /pods returns a list of Pods.</li> <li>POST /&lt;resourceNamePlural&gt; - Create a new resource from the JSON object provided by the client.</li> <li>GET /&lt;resourceNamePlural&gt;/&lt;name&gt; - Retrieves a single resource with the given name, e.g. GET /pods/first returns a Pod named 'first'. Should be constant time, and the resource should be bounded in size.</li> <li>DELETE /&lt;resourceNamePlural&gt;/&lt;name&gt; - Delete the single resource with the given name. DeleteOptions may specify gracePeriodSeconds, the optional duration in seconds before the object should be deleted. Individual kinds may declare fields which provide a default grace period, and different kinds may have differing kind-wide default grace periods. A user provided grace period overrides a default grace period, including the zero grace period ("now").</li> <li>DELETE /&lt;resourceNamePlural&gt; - Deletes a list of type &lt;resourceName&gt;, e.g. DELETE /pods a list of Pods.</li> <li>PUT /&lt;resourceNamePlural&gt;/&lt;name&gt; - Update or create the resource with the given name with the JSON object provided by the client. Whether a resource can be created with a PUT request depends on the particular resource's storage strategy configuration, specifically the <code>AllowCreateOnUpdate()</code> return value. Most built-in types do not allow this.</li> <li>PATCH /&lt;resourceNamePlural&gt;/&lt;name&gt; - Selectively modify the specified fields of the resource. See more information <a href="#patch-operations">below</a>.</li> <li>GET /&lt;resourceNamePlural&gt;?watch=true - Receive a stream of JSON objects corresponding to changes made to any resource of the given kind over time.</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">PATCH operations</h3><a id="user-content-patch-operations" class="anchor" aria-label="Permalink: PATCH operations" href="#patch-operations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The API supports three different PATCH operations, determined by their corresponding Content-Type header:</p> <ul dir="auto"> <li>JSON Patch, <code>Content-Type: application/json-patch+json</code> <ul dir="auto"> <li>As defined in <a href="https://tools.ietf.org/html/rfc6902" rel="nofollow">RFC6902</a>, a JSON Patch is a sequence of operations that are executed on the resource, e.g. <code>{"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}</code>. For more details on how to use JSON Patch, see the RFC.</li> </ul> </li> <li>Merge Patch, <code>Content-Type: application/merge-patch+json</code> <ul dir="auto"> <li>As defined in <a href="https://tools.ietf.org/html/rfc7386" rel="nofollow">RFC7386</a>, a Merge Patch is essentially a partial representation of the resource. The submitted JSON is "merged" with the current resource to create a new one, then the new one is saved. For more details on how to use Merge Patch, see the RFC.</li> </ul> </li> <li>Strategic Merge Patch, <code>Content-Type: application/strategic-merge-patch+json</code> <ul dir="auto"> <li>Strategic Merge Patch is a custom implementation of Merge Patch. For a detailed explanation of how it works and why it needed to be introduced, see <a href="/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md">here</a>.</li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Short-names and Categories</h2><a id="user-content-short-names-and-categories" class="anchor" aria-label="Permalink: Short-names and Categories" href="#short-names-and-categories"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Resource implementers can optionally include "short names" and categories in the discovery information published for a resource type, which clients may use as hints when resolving ambiguous user invocations.</p> <p dir="auto">For compiled-in resources, these are controlled by the REST handler <code>ShortNames() []string</code> and <code>Categories() []string</code> implementations.</p> <p dir="auto">For custom resources, these are controlled by the <code>.spec.names.shortNames</code> and <code>.spec.names.categories</code> fields in the CustomResourceDefinition.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Short-names</h3><a id="user-content-short-names" class="anchor" aria-label="Permalink: Short-names" href="#short-names"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Note: Due to unpredictable behavior when short names collide (with each other or with resource types), do not add new short names to built-in resources unless specifically allowed by API reviewers. See issues <a href="https://issue.k8s.io/117742#issuecomment-1545945336" rel="nofollow">#117742</a> and <a href="http://issue.k8s.io/108573" rel="nofollow">#108573</a>.</p> <p dir="auto">"Short names" listed in discovery may be used by clients as hints to resolve ambiguous user invocations to a single resource.</p> <p dir="auto">Examples of built-in short names include:</p> <ul dir="auto"> <li><code>ds</code> -&gt; <code>apps/v* daemonsets</code></li> <li><code>sts</code> -&gt; <code>apps/v* statefulsets</code></li> <li><code>hpa</code> -&gt; <code>autoscaling/v* horizontalpodautoscalers</code></li> </ul> <p dir="auto">For example, with only built-in API types served, <code>kubectl get sts</code> is equivalent to <code>kubectl get statefulsets.v1.apps</code>.</p> <p dir="auto">Short-name matches may be given lower priority than an exact match of a resource type, so use of short names increases potential for inconsistent behavior in clusters with custom resources installed, if those custom resource types overlap with short names.</p> <p dir="auto">Continuing the above example, if a custom resource with <code>.spec.names.plural</code> set to <code>sts</code> was installed in a cluster, <code>kubectl get sts</code> would switch to retrieving instances of the custom resource instead.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Categories</h3><a id="user-content-categories" class="anchor" aria-label="Permalink: Categories" href="#categories"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Note: Due to inconsistent behavior when categories collide with resource types, and difficulties knowing when it is safe to add new resources to an existing category, do not add new categories to built-in resources unless specifically allowed by API reviewers. See issues <a href="https://github.com/kubernetes/kubernetes/issues/7547#issuecomment-355835279" data-hovercard-type="issue" data-hovercard-url="/kubernetes/kubernetes/issues/7547/hovercard">#7547</a> <a href="https://github.com/kubernetes/kubernetes/issues/42885#issuecomment-531265679" data-hovercard-type="issue" data-hovercard-url="/kubernetes/kubernetes/issues/42885/hovercard">#42885</a>, and <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-cli/kubectl-conventions.md#rules-for-extending-special-resource-alias---all">considerations for adding to the "all" category</a> for examples of the difficulties encountered.</p> <p dir="auto">Categories listed in discovery may be used by clients as hints to resolve user invocations to multiple resources.</p> <p dir="auto">Examples of built-in categories and the resources they map to include:</p> <ul dir="auto"> <li><code>api-extensions</code> <ul dir="auto"> <li><code>apiregistration.k8s.io/v* apiservices</code></li> <li><code>admissionregistration.k8s.io/v* mutatingwebhookconfigurations</code></li> <li><code>admissionregistration.k8s.io/v* validatingwebhookconfigurations</code></li> <li><code>admissionregistration.k8s.io/v* validatingadmissionpolicies</code></li> <li><code>admissionregistration.k8s.io/v* validatingadmissionpolicybindings</code></li> <li><code>apiextensions.k8s.io/v* customresourcedefinitions</code></li> </ul> </li> <li><code>all</code> <ul dir="auto"> <li><code>v1 pods</code></li> <li><code>v1 replicationcontrollers</code></li> <li><code>v1 services</code></li> <li><code>apps/v* daemonsets</code></li> <li><code>apps/v* deployments</code></li> <li><code>apps/v* replicasets</code></li> <li><code>apps/v* statefulsets</code></li> <li><code>autoscaling/v* horizontalpodautoscalers</code></li> <li><code>batch/v* cronjobs</code></li> <li><code>batch/v* jobs</code></li> </ul> </li> </ul> <p dir="auto">With the above categories, and only built-in API types served, <code>kubectl get all</code> would be equivalent to <code>kubectl get pods.v1.,replicationcontrollers.v1.,services.v1.,daemonsets.v1.apps,deployments.v1.apps,replicasets.v1.apps,statefulsets.v1.apps,horizontalpodautoscalers.v2.autoscaling,cronjobs.v1.batch,jobs.v1.batch,</code>.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Idempotency</h2><a id="user-content-idempotency" class="anchor" aria-label="Permalink: Idempotency" href="#idempotency"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">All compatible Kubernetes APIs MUST support "name idempotency" and respond with an HTTP status code 409 when a request is made to POST an object that has the same name as an existing object in the system. See <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/names/" rel="nofollow">the identifiers docs</a> for details.</p> <p dir="auto">Names generated by the system may be requested using <code>metadata.generateName</code>. GenerateName indicates that the name should be made unique by the server prior to persisting it. A non-empty value for the field indicates the server should attempt to make the name unique (and the name returned to the client will be different than the name passed). The value of this field will be combined with a random suffix on the server if the Name field has not been provided. The provided value must be valid within the rules for Name, and may be truncated by the length of the suffix. If this field is specified, and Name is not present, the server will return a 409 with Reason <code>AlreadyExists</code> if the generated name exists, and the client should retry (after waiting at least the amount of time indicated in the Retry-After header, if it is present).</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Optional vs. Required</h2><a id="user-content-optional-vs-required" class="anchor" aria-label="Permalink: Optional vs. Required" href="#optional-vs-required"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Fields must be either optional or required.</p> <p dir="auto">Optional fields have the following properties:</p> <ul dir="auto"> <li>They have the <code>+optional</code> comment tag in Go.</li> <li>They are a pointer type in the Go definition (e.g. <code>AwesomeFlag *SomeFlag</code>) or have a built-in <code>nil</code> value (e.g. maps and slices).</li> <li>The API server should allow POSTing and PUTing a resource with this field unset.</li> </ul> <p dir="auto">In most cases, optional fields should also have the <code>omitempty</code> struct tag (the <code>omitempty</code> option specifies that the field should be omitted from the json encoding if the field has an empty value). However, If you want to have different logic for an optional field which is not provided vs. provided with empty values, do not use <code>omitempty</code> (e.g. <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="182620092" data-permission-text="Title is private" data-url="https://github.com/kubernetes/kubernetes/issues/34641" data-hovercard-type="issue" data-hovercard-url="/kubernetes/kubernetes/issues/34641/hovercard" href="https://github.com/kubernetes/kubernetes/issues/34641">kubernetes/kubernetes#34641</a>).</p> <p dir="auto">Note that for backward compatibility, any field that has the <code>omitempty</code> struct tag will be considered to be optional, but this may change in the future and having the <code>+optional</code> comment tag is highly recommended.</p> <p dir="auto">Required fields have the opposite properties, namely:</p> <ul dir="auto"> <li>They do not have an <code>+optional</code> comment tag.</li> <li>They do not have an <code>omitempty</code> struct tag.</li> <li>They are not a pointer type in the Go definition (e.g. <code>AnotherFlag SomeFlag</code>).</li> <li>The API server should not allow POSTing or PUTing a resource with this field unset.</li> </ul> <p dir="auto">Using the <code>+optional</code> or the <code>omitempty</code> tag causes OpenAPI documentation to reflect that the field is optional.</p> <p dir="auto">Using a pointer allows distinguishing unset from the zero value for that type. There are some cases where, in principle, a pointer is not needed for an optional field since the zero value is forbidden, and thus implies unset. There are examples of this in the codebase. However:</p> <ul dir="auto"> <li>it can be difficult for implementors to anticipate all cases where an empty value might need to be distinguished from a zero value</li> <li>structs are not omitted from encoder output even where omitempty is specified, which is messy;</li> <li>having a pointer consistently imply optional is clearer for users of the Go language client, and any other clients that use corresponding types</li> </ul> <p dir="auto">Therefore, we ask that pointers always be used with optional fields that do not have a built-in <code>nil</code> value.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Defaulting</h2><a id="user-content-defaulting" class="anchor" aria-label="Permalink: Defaulting" href="#defaulting"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">In general we want default values to be explicitly represented in our APIs, rather than asserting that "unspecified fields get the default behavior". This is important so that:</p> <ul dir="auto"> <li>default values can evolve and change in newer API versions</li> <li>the stored configuration depicts the full desired state, making it easier for the system to determine how to achieve the state, and for the user to know what to anticipate</li> </ul> <p dir="auto">There are 3 distinct ways that default values can be applied when creating or updating (including patch and apply) a resource:</p> <ol dir="auto"> <li>static: based on the requested API version and possibly other fields in the resource, fields can be assigned values during the API call</li> <li>admission control: based on the configured admission controllers and possibly other state in or out of the cluster, fields can be assigned values during the API call</li> <li>controllers: arbitrary changes (within the bounds of what is allowed) can be made to a resource after the API call has completed</li> </ol> <p dir="auto">Some care is required when deciding which mechanism to use and managing the semantics.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Static Defaults</h3><a id="user-content-static-defaults" class="anchor" aria-label="Permalink: Static Defaults" href="#static-defaults"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Static default values are specific to each API version. The default field values applied when creating an object with the "v1" API may be different than the values applied when using the "v2" API. In most cases, these values are defined as literal values by the API version (e.g. "if this field is not specified it defaults to 0").</p> <p dir="auto">In some cases, these values may be conditional on or deterministically derived from other fields (e.g. "if otherField is X then this field defaults to 0" or "this field defaults to the value of otherField"). Note that such derived defaults present a hazard in the face of updates - if the "other" field changes, the derived field may have to change, too. The static defaulting logic is unaware of updates and has no concept of "previous value", which means this inter-field relationship becomes the user's problem - they must update both the field they care about and the "other" field.</p> <p dir="auto">In very rare cases, these values may be allocated from some pool or determined by some other method (e.g. Service's IP and IP-family related fields need to consider other configuration settings).</p> <p dir="auto">These values are applied synchronously by the API server when decoding versioned data. For CREATE and UPDATE operations this is fairly straight-forward - when the API server receives a (versioned) request, the default values are immediately applied before any further processing. When the API call completes, all static defaults will have been set and stored. Subsequent GETs of the resource will include the default values explicitly. However, static defaults also apply when an object is read from storage (i.e. GET operations). This means that when someone GETs an "older" stored object, any fields which have been added to the API since that object was stored will be defaulted and returned according to the API version that is stored.</p> <p dir="auto">Static defaults are the best choice for values which are logically required, but which have a value that works well for most users. Static defaulting must not consider any state except the object being operated upon (and the complexity of Service API stands as an example of why).</p> <p dir="auto">Default values can be specified on a field using the <code>+default=</code> tag. Primitives will have their values directly assigned while structs will go through the JSON unmarshalling process. Fields that do not have an <code>omitempty</code> json tag will default to the zero value of their corresponding type if no default is assigned.</p> <p dir="auto">Refer to <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting" rel="nofollow">defaulting docs</a> for more information.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Admission Controlled Defaults</h3><a id="user-content-admission-controlled-defaults" class="anchor" aria-label="Permalink: Admission Controlled Defaults" href="#admission-controlled-defaults"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">In some cases, it is useful to set a default value which is not derived from the object in question. For example, when creating a PersistentVolumeClaim, the storage class must be specified. For many users, the best answer is "whatever the cluster admin has decided for the default". StorageClass is a different API than PersistentVolumeClaim, and which one is denoted as the default may change at any time. Thus this is not eligible for static defaulting.</p> <p dir="auto">Instead, we can provide a built-in admission controller or a MutatingWebhookConfiguration. Unlike static defaults, these may consider external state (such as annotations on StorageClass objects) when deciding default values, and must handle things like race conditions (e.g. a StorageClass is designated the default, but the admission controller has not yet seen that update). These admission controllers are strictly optional and can be disabled. As such, fields which are initialized this way must be strictly optional.</p> <p dir="auto">Like static defaults, these are run synchronously to the API operation in question, and when the API call completes, all static defaults will have been set. Subsequent GETs of the resource will include the default values explicitly.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Controller-Assigned Defaults (aka Late Initialization)</h3><a id="user-content-controller-assigned-defaults-aka-late-initialization" class="anchor" aria-label="Permalink: Controller-Assigned Defaults (aka Late Initialization)" href="#controller-assigned-defaults-aka-late-initialization"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Late initialization is when resource fields are set by a system controller after an object is created/updated (asynchronously). For example, the scheduler sets the <code>pod.spec.nodeName</code> field after the pod is created. It's a stretch to call this "defaulting" but since it is so common and useful, it is included here.</p> <p dir="auto">Like admission controlled defaults, these controllers may consider external state when deciding what values to set, must handle race conditions, and can be disabled. Fields which are initialized this way must be strictly optional (meaning observers will see the object without these fields set, and that is allowable and semantically correct).</p> <p dir="auto">Like all controllers, care must be taken to not clobber unrelated fields or values (e.g. in an array). Using one of the patch or apply mechanisms is recommended to facilitate composition and concurrency of controllers.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">What May Be Defaulted</h3><a id="user-content-what-may-be-defaulted" class="anchor" aria-label="Permalink: What May Be Defaulted" href="#what-may-be-defaulted"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">All forms of defaulting should only make the following types of modifications:</p> <ul dir="auto"> <li>Setting previously unset fields</li> <li>Adding keys to maps</li> <li>Adding values to arrays which have mergeable semantics (<code>+listType=map</code> tag or <code>patchStrategy:"merge"</code> attribute in the type definition)</li> </ul> <p dir="auto">In particular we never want to change or override a value that was provided by the user. If they requested something invalid, they should get an error.</p> <p dir="auto">These rules ensure that:</p> <ol dir="auto"> <li>a user (with sufficient privilege) can override any system-default behaviors by explicitly setting the fields that would otherwise have been defaulted</li> <li>updates from users can be merged with default values</li> </ol> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Considerations For PUT Operations</h3><a id="user-content-considerations-for-put-operations" class="anchor" aria-label="Permalink: Considerations For PUT Operations" href="#considerations-for-put-operations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Once an object has been created and defaults have been applied, it's very common for updates to happen over time. Kubernetes offers several ways of updating an object which preserve existing values in fields other than those being updated (e.g. strategic merge patch and server-side apply). There is, however, a less obvious way of updating objects which can have bad interactions with default values - PUT (aka <code>kubectl replace</code>).</p> <p dir="auto">The goal is that, for a given input (e.g. YAML file), PUT on an existing object should produce the same result as if you used that input to create the object. Calling PUT a second time with the same input should be idempotent and should not change the resource. Even a read-modify-write cycle is not a perfect solution in the face of version skew.</p> <p dir="auto">When an object is updated with a PUT, the API server will see the "old" object with previously assigned defaults and the "new" object with newly assigned defaults. For static defaults this can be a problem if the CREATE and the PUT used different API versions. For example, "v1" of an API might default a field to <code>false</code>, while "v2" defaults it to <code>true</code>. If an object was created via API v1 (field = <code>false</code>) and then replaced via API v2, the field will attempt to change to <code>true</code>. This can also be a problem when the values are allocated or derived from a source outside of the object in question (e.g. Service IPs).</p> <p dir="auto">For some APIs this is acceptable and actionable. For others, this may be disallowed by validation. In the latter case, the user will get an error about an attempt to change a field which is not even present in their YAML. This is especially dangerous when adding new fields - an older client may not even know about the existence of the field, making even a read-modify-write cycle fail. While it is "correct" (in the sense that it is really what they asked for with PUT), it is not helpful and is a bad UX.</p> <p dir="auto">When adding a field with a static or admission controlled default, this must be considered. If the field is immutable after creation, consider adding logic to manually "patch" the value from the "old" object into the "new" one when it has been "unset", rather than returning an error or allocating a different value (e.g. Service IPs). This will very often be what the user meant, even if it is not what they said. This may require setting the default in a different way (e.g. in the registry code which understands updates instead of in the versioned defaulting code which does not). Be careful to detect and report legitimate errors where the "new" value is specified but is different from the "old" value.</p> <p dir="auto">For controller-defaulted fields, the situation is even more unpleasant. Controllers do not have an opportunity to "patch" the value before the API operation is committed. If the "unset" value is allowed then it will be saved, and any watch clients will be notified. If the "unset" value is not allowed or mutations are otherwise disallowed, the user will get an error, and there's simply nothing we can do about it.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Concurrency Control and Consistency</h2><a id="user-content-concurrency-control-and-consistency" class="anchor" aria-label="Permalink: Concurrency Control and Consistency" href="#concurrency-control-and-consistency"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Kubernetes leverages the concept of <em>resource versions</em> to achieve optimistic concurrency. All Kubernetes resources have a "resourceVersion" field as part of their metadata. This resourceVersion is a string that identifies the internal version of an object that can be used by clients to determine when objects have changed. When a record is about to be updated, its version is checked against a pre-saved value, and if it doesn't match, the update fails with a StatusConflict (HTTP status code 409).</p> <p dir="auto">The resourceVersion is changed by the server every time an object is modified. If resourceVersion is included with the PUT operation the system will verify that there have not been other successful mutations to the resource during a read/modify/write cycle, by verifying that the current value of resourceVersion matches the specified value.</p> <p dir="auto">The resourceVersion is currently backed by <a href="https://etcd.io/docs/latest/learning/api/#key-value-pair" rel="nofollow">etcd's mod_revision</a>. However, it's important to note that the application should <em>not</em> rely on the implementation details of the versioning system maintained by Kubernetes. We may change the implementation of resourceVersion in the future, such as to change it to a timestamp or per-object counter.</p> <p dir="auto">The only way for a client to know the expected value of resourceVersion is to have received it from the server in response to a prior operation, typically a GET. This value MUST be treated as opaque by clients and passed unmodified back to the server. Clients should not assume that the resource version has meaning across namespaces, different kinds of resources, or different servers. Currently, the value of resourceVersion is set to match etcd's sequencer. You could think of it as a logical clock the API server can use to order requests. However, we expect the implementation of resourceVersion to change in the future, such as in the case we shard the state by kind and/or namespace, or port to another storage system.</p> <p dir="auto">In the case of a conflict, the correct client action at this point is to GET the resource again, apply the changes afresh, and try submitting again. This mechanism can be used to prevent races like the following:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Client #1 Client #2 GET Foo GET Foo Set Foo.Bar = &quot;one&quot; Set Foo.Baz = &quot;two&quot; PUT Foo PUT Foo"><pre class="notranslate"><code>Client #1 Client #2 GET Foo GET Foo Set Foo.Bar = "one" Set Foo.Baz = "two" PUT Foo PUT Foo </code></pre></div> <p dir="auto">When these sequences occur in parallel, either the change to Foo.Bar or the change to Foo.Baz can be lost.</p> <p dir="auto">On the other hand, when specifying the resourceVersion, one of the PUTs will fail, since whichever write succeeds changes the resourceVersion for Foo.</p> <p dir="auto">resourceVersion may be used as a precondition for other operations (e.g., GET, DELETE) in the future, such as for read-after-write consistency in the presence of caching.</p> <p dir="auto">"Watch" operations specify resourceVersion using a query parameter. It is used to specify the point at which to begin watching the specified resources. This may be used to ensure that no mutations are missed between a GET of a resource (or list of resources) and a subsequent Watch, even if the current version of the resource is more recent. This is currently the main reason that list operations (GET on a collection) return resourceVersion.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Serialization Format</h2><a id="user-content-serialization-format" class="anchor" aria-label="Permalink: Serialization Format" href="#serialization-format"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">APIs may return alternative representations of any resource in response to an Accept header or under alternative endpoints, but the default serialization for input and output of API responses MUST be JSON.</p> <p dir="auto">A protobuf encoding is also accepted for built-in resources. As proto is not self-describing, there is an envelope wrapper which describes the type of the contents.</p> <p dir="auto">All dates should be serialized as RFC3339 strings.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Units</h2><a id="user-content-units" class="anchor" aria-label="Permalink: Units" href="#units"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Units must either be explicit in the field name (e.g., <code>timeoutSeconds</code>), or must be specified as part of the value (e.g., <code>resource.Quantity</code>). Which approach is preferred is TBD, though currently we use the <code>fooSeconds</code> convention for durations.</p> <p dir="auto">Duration fields must be represented as integer fields with units being part of the field name (e.g. <code>leaseDurationSeconds</code>). We don't use Duration in the API since that would require clients to implement go-compatible parsing.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Selecting Fields</h2><a id="user-content-selecting-fields" class="anchor" aria-label="Permalink: Selecting Fields" href="#selecting-fields"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Some APIs may need to identify which field in a JSON object is invalid, or to reference a value to extract from a separate resource. The current recommendation is to use standard JavaScript syntax for accessing that field, assuming the JSON object was transformed into a JavaScript object, without the leading dot, such as <code>metadata.name</code>.</p> <p dir="auto">Examples:</p> <ul dir="auto"> <li>Find the field "current" in the object "state" in the second item in the array "fields": <code>fields[1].state.current</code></li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Object references</h2><a id="user-content-object-references" class="anchor" aria-label="Permalink: Object references" href="#object-references"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Object references on a namespaced type should usually refer only to objects in the same namespace. Because namespaces are a security boundary, cross namespace references can have unexpected impacts, including:</p> <ol dir="auto"> <li>leaking information about one namespace into another namespace. It's natural to place status messages or even bits of content about the referenced object in the original. This is a problem across namespaces.</li> <li>potential invasions into other namespaces. Often references give access to a piece of referred information, so being able to express "give me that one over there" is dangerous across namespaces without additional work for permission checks or opt-in's from both involved namespaces.</li> <li>referential integrity problems that one party cannot solve. Referencing namespace/B from namespace/A doesn't imply the power to control the other namespace. This means that you can refer to a thing you cannot create or update.</li> <li>unclear semantics on deletion. If a namespaced resource is referenced by other namespaces, should a delete of the referenced resource result in removal or should the referenced resource be force to remain.</li> <li>unclear semantics on creation. If a referenced resource is created after its reference, there is no way to know if it is the one that is expected or if it is a different one created with the same name.</li> </ol> <p dir="auto">Built-in types and ownerReferences do not support cross namespaces references. If a non-built-in types chooses to have cross-namespace references the semantics of the edge cases above should be clearly described and the permissions issues should be resolved. This could be done with a double opt-in (an opt-in from both the referrer and the refer-ee) or with secondary permissions checks performed in admission.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Naming of the reference field</h3><a id="user-content-naming-of-the-reference-field" class="anchor" aria-label="Permalink: Naming of the reference field" href="#naming-of-the-reference-field"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The name of the reference field should be of the format "{field}Ref", with "Ref" always included in the suffix.</p> <p dir="auto">The "{field}" component should be named to indicate the purpose of the reference. For example, "targetRef" in an endpoint indicates that the object reference specifies the target.</p> <p dir="auto">It is okay to have the "{field}" component indicate the resource type. For example, "secretRef" when referencing a secret. However, this comes with the risk of the field being a misnomer in the case that the field is expanded to reference more than one type.</p> <p dir="auto">In the case of a list of object references, the field should be of the format "{field}Refs", with the same guidance as the singular case above.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Referencing resources with multiple versions</h3><a id="user-content-referencing-resources-with-multiple-versions" class="anchor" aria-label="Permalink: Referencing resources with multiple versions" href="#referencing-resources-with-multiple-versions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Most resources will have multiple versions. For example, core resources will undergo version changes as it transitions from alpha to GA.</p> <p dir="auto">Controllers should assume that a version of a resource may change, and include appropriate error handling.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Handling of resources that do not exist</h3><a id="user-content-handling-of-resources-that-do-not-exist" class="anchor" aria-label="Permalink: Handling of resources that do not exist" href="#handling-of-resources-that-do-not-exist"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">There are multiple scenarios where a desired resource may not exist. Examples include:</p> <ul dir="auto"> <li>the desired version of the resource does not exist.</li> <li>race condition in the bootstrapping of a cluster resulting a resource not yet added.</li> <li>user error.</li> </ul> <p dir="auto">Controllers should be authored with the assumption that the referenced resource may not exist, and include error handling to make the issue clear to the user.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Validation of fields</h3><a id="user-content-validation-of-fields" class="anchor" aria-label="Permalink: Validation of fields" href="#validation-of-fields"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Many of the values used in an object reference are used as part of the API path. For example, the object name is used in the path to identify the object. Unsanitized, these values can be used to attempt to retrieve other resources, such as by using values with semantic meanings such as <code>..</code> or <code>/</code>.</p> <p dir="auto">Have the controller validate fields before using them as path segments in an API request, and emit an event to tell the user that the validation has failed.</p> <p dir="auto">See <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/names/" rel="nofollow">Object Names and IDs</a> for more information on legal object names.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Do not modify the referred object</h3><a id="user-content-do-not-modify-the-referred-object" class="anchor" aria-label="Permalink: Do not modify the referred object" href="#do-not-modify-the-referred-object"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">To minimize potential privilege escalation vectors, do not modify the object that is being referred to, or limit modification to objects in the same namespace and constrain the type of modification allowed (for example, the HorizontalPodAutoscaler controller only writes to the <code>/scale</code> subresource).</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Minimize copying or printing values to the referrer object</h3><a id="user-content-minimize-copying-or-printing-values-to-the-referrer-object" class="anchor" aria-label="Permalink: Minimize copying or printing values to the referrer object" href="#minimize-copying-or-printing-values-to-the-referrer-object"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">As the permissions of the controller can differ from the permissions of the author of the object the controller is managing, it is possible that the author of the object may not have permissions to view the referred object. As a result, the copying of any values about the referred object to the referrer object can be considered permissions escalations, enabling a user to read values that they would not have access to previously.</p> <p dir="auto">The same scenario applies to writing information about the referred object to events.</p> <p dir="auto">In general, do not write or print information retrieved from the referred object to the spec, other objects, or logs.</p> <p dir="auto">When it is necessary, consider whether these values would be ones that the author of the referrer object would have access to via other means (e.g. already required to correctly populate the object reference).</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Object References Examples</h3><a id="user-content-object-references-examples" class="anchor" aria-label="Permalink: Object References Examples" href="#object-references-examples"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The following sections illustrate recommended schemas for various object references scenarios.</p> <p dir="auto">The schemas outlined below are designed to enable purely additive fields as the types of referencable objects expand, and therefore are backwards compatible.</p> <p dir="auto">For example, it is possible to go from a single resource type to multiple resource types without a breaking change in the schema.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Single resource reference</h4><a id="user-content-single-resource-reference" class="anchor" aria-label="Permalink: Single resource reference" href="#single-resource-reference"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">A single kind object reference is straightforward in that the controller can hard-code most qualifiers needed to identify the object. As such as the only value needed to be provided is the name (and namespace, although cross-namespace references are discouraged):</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# for a single resource, the suffix should be Ref, with the field name # providing an indication as to the resource type referenced. secretRef: name: foo # namespace would generally not be needed and is discouraged, # as explained above. namespace: foo-namespace"><pre><span class="pl-c"><span class="pl-c">#</span> for a single resource, the suffix should be Ref, with the field name</span> <span class="pl-c"><span class="pl-c">#</span> providing an indication as to the resource type referenced.</span> <span class="pl-ent">secretRef</span>: <span class="pl-ent">name</span>: <span class="pl-s">foo</span> <span class="pl-c"><span class="pl-c">#</span> namespace would generally not be needed and is discouraged,</span> <span class="pl-c"><span class="pl-c">#</span> as explained above.</span> <span class="pl-ent">namespace</span>: <span class="pl-s">foo-namespace</span></pre></div> <p dir="auto">This schema should only be used when the intention is to always have the reference only be to a single resource. If extending to multiple resource types is possible, use the <a href="#multiple-resource-reference">multiple resource reference</a>.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Controller behavior</h5><a id="user-content-controller-behavior" class="anchor" aria-label="Permalink: Controller behavior" href="#controller-behavior"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The operator is expected to know the version, group, and resource name of the object it needs to retrieve the value from, and can use the discovery client or construct the API path directly.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Multiple resource reference</h4><a id="user-content-multiple-resource-reference" class="anchor" aria-label="Permalink: Multiple resource reference" href="#multiple-resource-reference"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Multi-kind object references are used when there is a bounded set of valid resource types that a reference can point to.</p> <p dir="auto">As with a single-kind object reference, the operator can supply missing fields, provided that the fields that are present are sufficient to uniquely identify the object resource type among the set of supported types.</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# guidance for the field name is the same as a single resource. fooRef: group: sns.services.k8s.aws resource: topics name: foo namespace: foo-namespace"><pre><span class="pl-c"><span class="pl-c">#</span> guidance for the field name is the same as a single resource.</span> <span class="pl-ent">fooRef</span>: <span class="pl-ent">group</span>: <span class="pl-s">sns.services.k8s.aws</span> <span class="pl-ent">resource</span>: <span class="pl-s">topics</span> <span class="pl-ent">name</span>: <span class="pl-s">foo</span> <span class="pl-ent">namespace</span>: <span class="pl-s">foo-namespace</span></pre></div> <p dir="auto">Although not always necessary to help a controller identify a resource type, “group” is included to avoid ambiguity when the resource exists in multiple groups. It also provides clarity to end users and enables copy-pasting of a reference without the referenced type changing due to a different controller handling the reference.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Kind vs. Resource</h5><a id="user-content-kind-vs-resource" class="anchor" aria-label="Permalink: Kind vs. Resource" href="#kind-vs-resource"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">A common point of confusion in object references is whether to construct references with a "kind" or "resource" field. Historically most object references in Kubernetes have used "kind". This is not as precise as "resource". Although each combination of "group" and "resource" must be unique within Kubernetes, the same is not always true for "group" and "kind". It is possible for multiple resources to make use of the same "kind".</p> <p dir="auto">Typically all objects in Kubernetes have a canonical primary resource - such as “pods” representing the way to create and delete resources of the “Pod” schema. While it is possible a resource schema cannot be directly created, such as a “Scale” object which is only used within the “scale” subresource of a number of workloads, most object references address the primary resource via its schema. In the context of object references, "kind" refers to the schema, not the resource.</p> <p dir="auto">If implementations of an object reference will always have a clear way to map kinds to resources, it is acceptable to use "kind" in the object reference. In general, this requires implementations to have a predefined mapping between kinds and resources (this is the case for built-in references which use "kind"). Relying on dynamic kind to resource mapping is not safe. Even if a "kind" only dynamically maps to a single resource initially, it's possible for another resource to be mounted that refers to the same "kind", potentially breaking any dynamic resource mapping.</p> <p dir="auto">If an object reference may be used to reference resources of arbitrary types and the mapping between kind and resource could be ambiguous, "resource" should be used in the object reference.</p> <p dir="auto">The Ingress API provides a good example of where "kind" is acceptable for an object reference. The API supports a backend reference as an extension point. Implementations can use this to support forwarding traffic to custom targets such as a storage bucket. Importantly, the supported target types are clearly defined by each implementation of the API and there is no ambiguity for which resource a kind maps to. This is because each Ingress implementation has a hard-coded mapping of kind to resource.</p> <p dir="auto">The object reference above would look like this if it were using "kind" instead of "resource":</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="fooRef: group: sns.services.k8s.aws kind: Topic name: foo namespace: foo-namespace"><pre><span class="pl-ent">fooRef</span>: <span class="pl-ent">group</span>: <span class="pl-s">sns.services.k8s.aws</span> <span class="pl-ent">kind</span>: <span class="pl-s">Topic</span> <span class="pl-ent">name</span>: <span class="pl-s">foo</span> <span class="pl-ent">namespace</span>: <span class="pl-s">foo-namespace</span></pre></div> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Controller behavior</h5><a id="user-content-controller-behavior-1" class="anchor" aria-label="Permalink: Controller behavior" href="#controller-behavior-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The operator can store a map of (group,resource) to the version of that resource it desires. From there, it can construct the full path to the resource, and retrieve the object.</p> <p dir="auto">It is also possible to have the controller choose a version that it finds via the discovery client. However, as schemas can vary across different versions of a resource, the controller must also handle these differences.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Generic object reference</h4><a id="user-content-generic-object-reference" class="anchor" aria-label="Permalink: Generic object reference" href="#generic-object-reference"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">A generic object reference is used when the desire is to provide a pointer to some object to simplify discovery for the user. For example, this could be used to reference a target object for a <code>core.v1.Event</code> that occurred.</p> <p dir="auto">With a generic object reference, it is not possible to extract any information about the referenced object aside from what is standard (e.g. ObjectMeta). Since any standard fields exist in any version of a resource, it is possible to not include version in this case:</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="fooObjectRef: group: operator.openshift.io resource: openshiftapiservers name: cluster # namespace is unset if the resource is cluster-scoped, or lives in the # same namespace as the referrer."><pre><span class="pl-ent">fooObjectRef</span>: <span class="pl-ent">group</span>: <span class="pl-s">operator.openshift.io</span> <span class="pl-ent">resource</span>: <span class="pl-s">openshiftapiservers</span> <span class="pl-ent">name</span>: <span class="pl-s">cluster</span> <span class="pl-c"><span class="pl-c">#</span> namespace is unset if the resource is cluster-scoped, or lives in the</span> <span class="pl-c"><span class="pl-c">#</span> same namespace as the referrer.</span></pre></div> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Controller behavior</h5><a id="user-content-controller-behavior-2" class="anchor" aria-label="Permalink: Controller behavior" href="#controller-behavior-2"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The operator would be expected to find the resource via the discovery client (as the version is not supplied). As any retrievable field would be common to all objects, any version of the resource should do.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Field reference</h4><a id="user-content-field-reference" class="anchor" aria-label="Permalink: Field reference" href="#field-reference"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">A field reference is used when the desire is to extract a value from a specific field in a referenced object.</p> <p dir="auto">Field references differ from other reference types, as the operator has no knowledge of the object prior to the reference. Since the schema of an object can differ for different versions of a resource, this means that a “version” is required for this type of reference.</p> <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="fooFieldRef: version: v1 # version of the resource # group is elided in the ConfigMap example, since it has a blank group in the OpenAPI spec. resource: configmaps fieldPath: data.foo"><pre><span class="pl-ent">fooFieldRef</span>: <span class="pl-ent">version</span>: <span class="pl-c1">v1</span> <span class="pl-c"><span class="pl-c">#</span> version of the resource</span> <span class="pl-c"><span class="pl-c">#</span> group is elided in the ConfigMap example, since it has a blank group in the OpenAPI spec.</span> <span class="pl-ent">resource</span>: <span class="pl-s">configmaps</span> <span class="pl-ent">fieldPath</span>: <span class="pl-s">data.foo</span></pre></div> <p dir="auto">The fieldPath should point to a single value, and use <a href="#selecting-fields">the recommended field selector notation</a> to denote the field path.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Controller behavior</h5><a id="user-content-controller-behavior-3" class="anchor" aria-label="Permalink: Controller behavior" href="#controller-behavior-3"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">In this scenario, the user will supply all of the required path elements: group, version, resource, name, and possibly namespace. As such, the controller can construct the API prefix and query it without the use of the discovery client:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/apis/{group}/{version}/{resource}/"><pre class="notranslate"><code>/apis/{group}/{version}/{resource}/ </code></pre></div> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">HTTP Status codes</h2><a id="user-content-http-status-codes" class="anchor" aria-label="Permalink: HTTP Status codes" href="#http-status-codes"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The server will respond with HTTP status codes that match the HTTP spec. See the section below for a breakdown of the types of status codes the server will send.</p> <p dir="auto">The following HTTP status codes may be returned by the API.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Success codes</h4><a id="user-content-success-codes" class="anchor" aria-label="Permalink: Success codes" href="#success-codes"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li><code>200 StatusOK</code> <ul dir="auto"> <li>Indicates that the request completed successfully.</li> </ul> </li> <li><code>201 StatusCreated</code> <ul dir="auto"> <li>Indicates that the request to create kind completed successfully.</li> </ul> </li> <li><code>204 StatusNoContent</code> <ul dir="auto"> <li>Indicates that the request completed successfully, and the response contains no body.</li> <li>Returned in response to HTTP OPTIONS requests.</li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Error codes</h4><a id="user-content-error-codes" class="anchor" aria-label="Permalink: Error codes" href="#error-codes"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li> <p dir="auto"><code>307 StatusTemporaryRedirect</code></p> <ul dir="auto"> <li>Indicates that the address for the requested resource has changed.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Follow the redirect.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>400 StatusBadRequest</code></p> <ul dir="auto"> <li>Indicates the requested is invalid.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>401 StatusUnauthorized</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but refuses to take any further action, because the client must provide authorization. If the client has provided authorization, the server is indicating the provided authorization is unsuitable or invalid.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>If the user has not supplied authorization information, prompt them for the appropriate credentials. If the user has supplied authorization information, inform them their credentials were rejected and optionally prompt them again.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>403 StatusForbidden</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but refuses to take any further action, because it is configured to deny access for some reason to the requested resource by the client.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>404 StatusNotFound</code></p> <ul dir="auto"> <li>Indicates that the requested resource does not exist.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>405 StatusMethodNotAllowed</code></p> <ul dir="auto"> <li>Indicates that the action the client attempted to perform on the resource was not supported by the code.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>409 StatusConflict</code></p> <ul dir="auto"> <li>Indicates that either the resource the client attempted to create already exists or the requested update operation cannot be completed due to a conflict.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>If creating a new resource: <ul dir="auto"> <li>Either change the identifier and try again, or GET and compare the fields in the pre-existing object and issue a PUT/update to modify the existing object.</li> </ul> </li> <li>If updating an existing resource: <ul dir="auto"> <li>See <code>Conflict</code> from the <code>status</code> response section below on how to retrieve more information about the nature of the conflict.</li> <li>GET and compare the fields in the pre-existing object, merge changes (if still valid according to preconditions), and retry with the updated request (including <code>ResourceVersion</code>).</li> </ul> </li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>410 StatusGone</code></p> <ul dir="auto"> <li>Indicates that the item is no longer available at the server and no forwarding address is known.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>422 StatusUnprocessableEntity</code></p> <ul dir="auto"> <li>Indicates that the requested create or update operation cannot be completed due to invalid data provided as part of the request.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Do not retry. Fix the request.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>429 StatusTooManyRequests</code></p> <ul dir="auto"> <li>Indicates that either the client rate limit has been exceeded or the server has received more requests than it can process.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Read the <code>Retry-After</code> HTTP header from the response, and wait at least that long before retrying.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>500 StatusInternalServerError</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but either an unexpected internal error occurred and the outcome of the call is unknown, or the server cannot complete the action in a reasonable time (this may be due to temporary server load or a transient communication issue with another server).</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Retry with exponential backoff.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>503 StatusServiceUnavailable</code></p> <ul dir="auto"> <li>Indicates that required service is unavailable.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Retry with exponential backoff.</li> </ul> </li> </ul> </li> <li> <p dir="auto"><code>504 StatusServerTimeout</code></p> <ul dir="auto"> <li>Indicates that the request could not be completed within the given time. Clients can get this response ONLY when they specified a timeout param in the request.</li> <li>Suggested client recovery behavior: <ul dir="auto"> <li>Increase the value of the timeout param and retry with exponential backoff.</li> </ul> </li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Response Status Kind</h2><a id="user-content-response-status-kind" class="anchor" aria-label="Permalink: Response Status Kind" href="#response-status-kind"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Kubernetes will always return the <code>Status</code> kind from any API endpoint when an error occurs. Clients SHOULD handle these types of objects when appropriate.</p> <p dir="auto">A <code>Status</code> kind will be returned by the API in two cases:</p> <ul dir="auto"> <li>When an operation is not successful (i.e. when the server would return a non 2xx HTTP status code).</li> <li>When a HTTP <code>DELETE</code> call is successful.</li> </ul> <p dir="auto">The status object is encoded as JSON and provided as the body of the response. The status object contains fields for humans and machine consumers of the API to get more detailed information for the cause of the failure. The information in the status object supplements, but does not override, the HTTP status code's meaning. When fields in the status object have the same meaning as generally defined HTTP headers and that header is returned with the response, the header should be considered as having higher priority.</p> <p dir="auto"><strong>Example:</strong></p> <div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ curl -v -k -H &quot;Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc&quot; https://10.240.122.184:443/api/v1/namespaces/default/pods/grafana &gt; GET /api/v1/namespaces/default/pods/grafana HTTP/1.1 &gt; User-Agent: curl/7.26.0 &gt; Host: 10.240.122.184 &gt; Accept: */* &gt; Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc &gt; &lt; HTTP/1.1 404 Not Found &lt; Content-Type: application/json &lt; Date: Wed, 20 May 2015 18:10:42 GMT &lt; Content-Length: 232 &lt; { &quot;kind&quot;: &quot;Status&quot;, &quot;apiVersion&quot;: &quot;v1&quot;, &quot;metadata&quot;: {}, &quot;status&quot;: &quot;Failure&quot;, &quot;message&quot;: &quot;pods \&quot;grafana\&quot; not found&quot;, &quot;reason&quot;: &quot;NotFound&quot;, &quot;details&quot;: { &quot;name&quot;: &quot;grafana&quot;, &quot;kind&quot;: &quot;pods&quot; }, &quot;code&quot;: 404 }"><pre>$ <span class="pl-s1">curl -v -k -H <span class="pl-s"><span class="pl-pds">"</span>Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc<span class="pl-pds">"</span></span> https://10.240.122.184:443/api/v1/namespaces/default/pods/grafana</span> &gt; <span class="pl-s1">GET /api/v1/namespaces/default/pods/grafana HTTP/1.1</span> &gt; <span class="pl-s1">User-Agent: curl/7.26.0</span> &gt; <span class="pl-s1">Host: 10.240.122.184</span> &gt; <span class="pl-s1">Accept: <span class="pl-k">*</span>/<span class="pl-k">*</span></span> &gt; <span class="pl-s1">Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc</span> &gt; <span class="pl-c1">&lt; HTTP/1.1 404 Not Found</span> <span class="pl-c1">&lt; Content-Type: application/json</span> <span class="pl-c1">&lt; Date: Wed, 20 May 2015 18:10:42 GMT</span> <span class="pl-c1">&lt; Content-Length: 232</span> <span class="pl-c1">&lt;</span> <span class="pl-c1">{</span> <span class="pl-c1"> "kind": "Status",</span> <span class="pl-c1"> "apiVersion": "v1",</span> <span class="pl-c1"> "metadata": {},</span> <span class="pl-c1"> "status": "Failure",</span> <span class="pl-c1"> "message": "pods \"grafana\" not found",</span> <span class="pl-c1"> "reason": "NotFound",</span> <span class="pl-c1"> "details": {</span> <span class="pl-c1"> "name": "grafana",</span> <span class="pl-c1"> "kind": "pods"</span> <span class="pl-c1"> },</span> <span class="pl-c1"> "code": 404</span> <span class="pl-c1">}</span></pre></div> <p dir="auto"><code>status</code> field contains one of two possible values:</p> <ul dir="auto"> <li><code>Success</code></li> <li><code>Failure</code></li> </ul> <p dir="auto"><code>message</code> may contain human-readable description of the error</p> <p dir="auto"><code>reason</code> may contain a machine-readable, one-word, CamelCase description of why this operation is in the <code>Failure</code> status. If this value is empty there is no information available. The <code>reason</code> clarifies an HTTP status code but does not override it.</p> <p dir="auto"><code>details</code> may contain extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.</p> <p dir="auto">Possible values for the <code>reason</code> and <code>details</code> fields:</p> <ul dir="auto"> <li> <p dir="auto"><code>BadRequest</code></p> <ul dir="auto"> <li>Indicates that the request itself was invalid, because the request doesn't make any sense, for example deleting a read-only object.</li> <li>This is different than <code>status reason</code> <code>Invalid</code> above which indicates that the API call could possibly succeed, but the data was invalid.</li> <li>API calls that return BadRequest can never succeed.</li> <li>Http status code: <code>400 StatusBadRequest</code></li> </ul> </li> <li> <p dir="auto"><code>Unauthorized</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but refuses to take any further action without the client providing appropriate authorization. If the client has provided authorization, this error indicates the provided credentials are insufficient or invalid.</li> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>The kind attribute of the unauthorized resource (on some operations may differ from the requested resource).</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>The identifier of the unauthorized resource.</li> </ul> </li> </ul> </li> <li>HTTP status code: <code>401 StatusUnauthorized</code></li> </ul> </li> <li> <p dir="auto"><code>Forbidden</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but refuses to take any further action, because it is configured to deny access for some reason to the requested resource by the client.</li> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>The kind attribute of the forbidden resource (on some operations may differ from the requested resource).</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>The identifier of the forbidden resource.</li> </ul> </li> </ul> </li> <li>HTTP status code: <code>403 StatusForbidden</code></li> </ul> </li> <li> <p dir="auto"><code>NotFound</code></p> <ul dir="auto"> <li>Indicates that one or more resources required for this operation could not be found.</li> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>The kind attribute of the missing resource (on some operations may differ from the requested resource).</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>The identifier of the missing resource.</li> </ul> </li> </ul> </li> <li>HTTP status code: <code>404 StatusNotFound</code></li> </ul> </li> <li> <p dir="auto"><code>AlreadyExists</code></p> <ul dir="auto"> <li>Indicates that the resource you are creating already exists.</li> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>The kind attribute of the conflicting resource.</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>The identifier of the conflicting resource.</li> </ul> </li> </ul> </li> <li>HTTP status code: <code>409 StatusConflict</code></li> </ul> </li> <li> <p dir="auto"><code>Conflict</code></p> <ul dir="auto"> <li>Indicates that the requested update operation cannot be completed due to a conflict. The client may need to alter the request. Each resource may define custom details that indicate the nature of the conflict.</li> <li>HTTP status code: <code>409 StatusConflict</code></li> </ul> </li> <li> <p dir="auto"><code>Invalid</code></p> <ul dir="auto"> <li>Indicates that the requested create or update operation cannot be completed due to invalid data provided as part of the request.</li> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>the kind attribute of the invalid resource</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>the identifier of the invalid resource</li> </ul> </li> <li><code>causes</code> <ul dir="auto"> <li>One or more <code>StatusCause</code> entries indicating the data in the provided resource that was invalid. The <code>reason</code>, <code>message</code>, and <code>field</code> attributes will be set.</li> </ul> </li> </ul> </li> <li>HTTP status code: <code>422 StatusUnprocessableEntity</code></li> </ul> </li> <li> <p dir="auto"><code>Timeout</code></p> <ul dir="auto"> <li>Indicates that the request could not be completed within the given time. Clients may receive this response if the server has decided to rate limit the client, or if the server is overloaded and cannot process the request at this time.</li> <li>Http status code: <code>429 TooManyRequests</code></li> <li>The server should set the <code>Retry-After</code> HTTP header and return <code>retryAfterSeconds</code> in the details field of the object. A value of <code>0</code> is the default.</li> </ul> </li> <li> <p dir="auto"><code>ServerTimeout</code></p> <ul dir="auto"> <li>Indicates that the server can be reached and understood the request, but cannot complete the action in a reasonable time. This maybe due to temporary server load or a transient communication issue with another server. <ul dir="auto"> <li>Details (optional): <ul dir="auto"> <li><code>kind string</code> <ul dir="auto"> <li>The kind attribute of the resource being acted on.</li> </ul> </li> <li><code>name string</code> <ul dir="auto"> <li>The operation that is being attempted.</li> </ul> </li> </ul> </li> </ul> </li> <li>The server should set the <code>Retry-After</code> HTTP header and return <code>retryAfterSeconds</code> in the details field of the object. A value of <code>0</code> is the default.</li> <li>Http status code: <code>504 StatusServerTimeout</code></li> </ul> </li> <li> <p dir="auto"><code>MethodNotAllowed</code></p> <ul dir="auto"> <li>Indicates that the action the client attempted to perform on the resource was not supported by the code.</li> <li>For instance, attempting to delete a resource that can only be created.</li> <li>API calls that return MethodNotAllowed can never succeed.</li> <li>Http status code: <code>405 StatusMethodNotAllowed</code></li> </ul> </li> <li> <p dir="auto"><code>InternalError</code></p> <ul dir="auto"> <li>Indicates that an internal error occurred, it is unexpected and the outcome of the call is unknown.</li> <li>Details (optional): <ul dir="auto"> <li><code>causes</code> <ul dir="auto"> <li>The original error.</li> </ul> </li> </ul> </li> <li>Http status code: <code>500 StatusInternalServerError</code> <code>code</code> may contain the suggested HTTP return code for this status.</li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Events</h2><a id="user-content-events" class="anchor" aria-label="Permalink: Events" href="#events"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Events are complementary to status information, since they can provide some historical information about status and occurrences in addition to current or previous status. Generate events for situations users or administrators should be alerted about.</p> <p dir="auto">Choose a unique, specific, short, CamelCase reason for each event category. For example, <code>FreeDiskSpaceInvalid</code> is a good event reason because it is likely to refer to just one situation, but <code>Started</code> is not a good reason because it doesn't sufficiently indicate what started, even when combined with other event fields.</p> <p dir="auto"><code>Error creating foo</code> or <code>Error creating foo %s</code> would be appropriate for an event message, with the latter being preferable, since it is more informational.</p> <p dir="auto">Accumulate repeated events in the client, especially for frequent events, to reduce data volume, load on the system, and noise exposed to users.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Naming conventions</h2><a id="user-content-naming-conventions" class="anchor" aria-label="Permalink: Naming conventions" href="#naming-conventions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>Go field names must be PascalCase. JSON field names must be camelCase. Other than capitalization of the initial letter, the two should almost always match. No underscores or dashes in either.</li> <li>Field and resource names should be declarative, not imperative (SomethingDoer, DoneBy, DoneAt).</li> <li>Use <code>Node</code> where referring to the node resource in the context of the cluster. Use <code>Host</code> where referring to properties of the individual physical/virtual system, such as <code>hostname</code>, <code>hostPath</code>, <code>hostNetwork</code>, etc.</li> <li><code>FooController</code> is a deprecated kind naming convention. Name the kind after the thing being controlled instead (e.g., <code>Job</code> rather than <code>JobController</code>).</li> <li>The name of a field that specifies the time at which <code>something</code> occurs should be called <code>somethingTime</code>. Do not use <code>stamp</code> (e.g., <code>creationTimestamp</code>).</li> <li>We use the <code>fooSeconds</code> convention for durations, as discussed in the <a href="#units">units subsection</a>. <ul dir="auto"> <li><code>fooPeriodSeconds</code> is preferred for periodic intervals and other waiting periods (e.g., over <code>fooIntervalSeconds</code>).</li> <li><code>fooTimeoutSeconds</code> is preferred for inactivity/unresponsiveness deadlines.</li> <li><code>fooDeadlineSeconds</code> is preferred for activity completion deadlines.</li> </ul> </li> <li>Do not use abbreviations in the API, except where they are extremely commonly used, such as "id", "args", or "stdin".</li> <li>Acronyms should similarly only be used when extremely commonly known. All letters in the acronym should have the same case, using the appropriate case for the situation. For example, at the beginning of a field name, the acronym should be all lowercase, such as "httpGet". Where used as a constant, all letters should be uppercase, such as "TCP" or "UDP".</li> <li>The name of a field referring to another resource of kind <code>Foo</code> by name should be called <code>fooName</code>. The name of a field referring to another resource of kind <code>Foo</code> by ObjectReference (or subset thereof) should be called <code>fooRef</code>.</li> <li>More generally, include the units and/or type in the field name if they could be ambiguous and they are not specified by the value or value type.</li> <li>The name of a field expressing a boolean property called 'fooable' should be called <code>Fooable</code>, not <code>IsFooable</code>.</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Namespace Names</h3><a id="user-content-namespace-names" class="anchor" aria-label="Permalink: Namespace Names" href="#namespace-names"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>The name of a namespace must be a <a href="https://git.k8s.io/design-proposals-archive/architecture/identifiers.md" rel="nofollow">DNS_LABEL</a>.</li> <li>The <code>kube-</code> prefix is reserved for Kubernetes system namespaces, e.g. <code>kube-system</code> and <code>kube-public</code>.</li> <li>See <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/" rel="nofollow">the namespace docs</a> for more information.</li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Label, selector, and annotation conventions</h2><a id="user-content-label-selector-and-annotation-conventions" class="anchor" aria-label="Permalink: Label, selector, and annotation conventions" href="#label-selector-and-annotation-conventions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Labels are the domain of users. They are intended to facilitate organization and management of API resources using attributes that are meaningful to users, as opposed to meaningful to the system. Think of them as user-created mp3 or email inbox labels, as opposed to the directory structure used by a program to store its data. The former enables the user to apply an arbitrary ontology, whereas the latter is implementation-centric and inflexible. Users will use labels to select resources to operate on, display label values in CLI/UI columns, etc. Users should always retain full power and flexibility over the label schemas they apply to labels in their namespaces.</p> <p dir="auto">However, we should support conveniences for common cases by default. For example, what we now do in ReplicationController is automatically set the RC's selector and labels to the labels in the pod template by default, if they are not already set. That ensures that the selector will match the template, and that the RC can be managed using the same labels as the pods it creates. Note that once we generalize selectors, it won't necessarily be possible to unambiguously generate labels that match an arbitrary selector.</p> <p dir="auto">If the user wants to apply additional labels to the pods that it doesn't select upon, such as to facilitate adoption of pods or in the expectation that some label values will change, they can set the selector to a subset of the pod labels. Similarly, the RC's labels could be initialized to a subset of the pod template's labels, or could include additional/different labels.</p> <p dir="auto">For disciplined users managing resources within their own namespaces, it's not that hard to consistently apply schemas that ensure uniqueness. One just needs to ensure that at least one value of some label key in common differs compared to all other comparable resources. We could/should provide a verification tool to check that. However, development of conventions similar to the examples in <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/" rel="nofollow">Labels</a> make uniqueness straightforward. Furthermore, relatively narrowly used namespaces (e.g., per environment, per application) can be used to reduce the set of resources that could potentially cause overlap.</p> <p dir="auto">In cases where users could be running misc. examples with inconsistent schemas, or where tooling or components need to programmatically generate new objects to be selected, there needs to be a straightforward way to generate unique label sets. A simple way to ensure uniqueness of the set is to ensure uniqueness of a single label value, such as by using a resource name, uid, resource hash, or generation number.</p> <p dir="auto">Problems with uids and hashes, however, include that they have no semantic meaning to the user, are not memorable nor readily recognizable, and are not predictable. Lack of predictability obstructs use cases such as creation of a replication controller from a pod, such as people want to do when exploring the system, bootstrapping a self-hosted cluster, or deletion and re-creation of a new RC that adopts the pods of the previous one, such as to rename it. Generation numbers are more predictable and much clearer, assuming there is a logical sequence. Fortunately, for deployments that's the case. For jobs, use of creation timestamps is common internally. Users should always be able to turn off auto-generation, in order to permit some of the scenarios described above. Note that auto-generated labels will also become one more field that needs to be stripped out when cloning a resource, within a namespace, in a new namespace, in a new cluster, etc., and will need to be ignored around when updating a resource via patch or read-modify-write sequence.</p> <p dir="auto">Inclusion of a system prefix in a label key is fairly hostile to UX. A prefix is only necessary in the case that the user cannot choose the label key, in order to avoid collisions with user-defined labels. However, I firmly believe that the user should always be allowed to select the label keys to use on their resources, so it should always be possible to override default label keys.</p> <p dir="auto">Therefore, resources supporting auto-generation of unique labels should have a <code>uniqueLabelKey</code> field, so that the user could specify the key if they wanted to, but if unspecified, it could be set by default, such as to the resource type, like job, deployment, or replicationController. The value would need to be at least spatially unique, and perhaps temporally unique in the case of job.</p> <p dir="auto">Annotations have very different intended usage from labels. They are primarily generated and consumed by tooling and system extensions, or are used by end-users to engage non-standard behavior of components. For example, an annotation might be used to indicate that an instance of a resource expects additional handling by non-kubernetes controllers. Annotations may carry arbitrary payloads, including JSON documents. Like labels, annotation keys can be prefixed with a governing domain (e.g. <code>example.com/key-name</code>). Unprefixed keys (e.g. <code>key-name</code>) are reserved for end-users. Third-party components must use prefixed keys. Key prefixes under the "kubernetes.io" and "k8s.io" domains are reserved for use by the kubernetes project and must not be used by third-parties.</p> <p dir="auto">In early versions of Kubernetes, some in-development features represented new API fields as annotations, generally with the form <code>something.alpha.kubernetes.io/name</code> or <code>something.beta.kubernetes.io/name</code> (depending on our confidence in it). This pattern is deprecated. Some such annotations may still exist, but no new annotations may be defined. New API fields are now developed as regular fields.</p> <p dir="auto">Other advice regarding use of labels, annotations, taints, and other generic map keys by Kubernetes components and tools:</p> <ul dir="auto"> <li>Key names should be all lowercase, with words separated by dashes instead of camelCase <ul dir="auto"> <li>For instance, prefer <code>foo.kubernetes.io/foo-bar</code> over <code>foo.kubernetes.io/fooBar</code>, prefer <code>desired-replicas</code> over <code>DesiredReplicas</code></li> </ul> </li> <li>Unprefixed keys are reserved for end-users. All other labels and annotations must be prefixed.</li> <li>Key prefixes under "kubernetes.io" and "k8s.io" are reserved for the Kubernetes project. <ul dir="auto"> <li>Such keys are effectively part of the kubernetes API and may be subject to deprecation and compatibility policies.</li> <li>"kubernetes.io" is the preferred form for labels and annotations, "k8s.io" should not be used for new map keys.</li> </ul> </li> <li>Key names, including prefixes, should be precise enough that a user could plausibly understand where it came from and what it is for.</li> <li>Key prefixes should carry as much context as possible. <ul dir="auto"> <li>For instance, prefer <code>subsystem.kubernetes.io/parameter</code> over <code>kubernetes.io/subsystem-parameter</code></li> </ul> </li> <li>Use annotations to store API extensions that the controller responsible for the resource doesn't need to know about, experimental fields that aren't intended to be generally used API fields, etc. Beware that annotations aren't automatically handled by the API conversion machinery.</li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">WebSockets and SPDY</h2><a id="user-content-websockets-and-spdy" class="anchor" aria-label="Permalink: WebSockets and SPDY" href="#websockets-and-spdy"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Some of the API operations exposed by Kubernetes involve transfer of binary streams between the client and a container, including attach, exec, portforward, and logging. The API therefore exposes certain operations over upgradeable HTTP connections (<a href="https://tools.ietf.org/html/rfc2817" rel="nofollow">described in RFC 2817</a>) via the WebSocket and SPDY protocols. These actions are exposed as subresources with their associated verbs (exec, log, attach, and portforward) and are requested via a GET (to support JavaScript in a browser) and POST (semantically accurate).</p> <p dir="auto">There are two primary protocols in use today:</p> <ol dir="auto"> <li> <p dir="auto">Streamed channels</p> <p dir="auto">When dealing with multiple independent binary streams of data such as the remote execution of a shell command (writing to STDIN, reading from STDOUT and STDERR) or forwarding multiple ports the streams can be multiplexed onto a single TCP connection. Kubernetes supports a SPDY based framing protocol that leverages SPDY channels and a WebSocket framing protocol that multiplexes multiple channels onto the same stream by prefixing each binary chunk with a byte indicating its channel. The WebSocket protocol supports an optional subprotocol that handles base64-encoded bytes from the client and returns base64-encoded bytes from the server and character based channel prefixes ('0', '1', '2') for ease of use from JavaScript in a browser.</p> </li> <li> <p dir="auto">Streaming response</p> <p dir="auto">The default log output for a channel of streaming data is an HTTP Chunked Transfer-Encoding, which can return an arbitrary stream of binary data from the server. Browser-based JavaScript is limited in its ability to access the raw data from a chunked response, especially when very large amounts of logs are returned, and in future API calls it may be desirable to transfer large files. The streaming API endpoints support an optional WebSocket upgrade that provides a unidirectional channel from the server to the client and chunks data as binary WebSocket frames. An optional WebSocket subprotocol is exposed that base64 encodes the stream before returning it to the client.</p> </li> </ol> <p dir="auto">Clients should use the SPDY protocols if their clients have native support, or WebSockets as a fallback. Note that WebSockets is susceptible to Head-of-Line blocking and so clients must read and process each message sequentially. In the future, an HTTP/2 implementation will be exposed that deprecates SPDY.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Validation</h2><a id="user-content-validation" class="anchor" aria-label="Permalink: Validation" href="#validation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">API objects are validated upon receipt by the apiserver. Validation errors are flagged and returned to the caller in a <code>Failure</code> status with <code>reason</code> set to <code>Invalid</code>. In order to facilitate consistent error messages, we ask that validation logic adheres to the following guidelines whenever possible (though exceptional cases will exist).</p> <ul dir="auto"> <li>Be as precise as possible.</li> <li>Telling users what they CAN do is more useful than telling them what they CANNOT do.</li> <li>When asserting a requirement in the positive, use "must". Examples: "must be greater than 0", "must match regex '[a-z]+'". Words like "should" imply that the assertion is optional, and must be avoided.</li> <li>When asserting a formatting requirement in the negative, use "must not". Example: "must not contain '..'". Words like "should not" imply that the assertion is optional, and must be avoided.</li> <li>When asserting a behavioral requirement in the negative, use "may not". Examples: "may not be specified when otherField is empty", "only <code>name</code> may be specified".</li> <li>When referencing a literal string value, indicate the literal in single-quotes. Example: "must not contain '..'".</li> <li>When referencing another field name, indicate the name in back-quotes. Example: "must be greater than `request`".</li> <li>When specifying inequalities, use words rather than symbols. Examples: "must be less than 256", "must be greater than or equal to 0". Do not use words like "larger than", "bigger than", "more than", "higher than", etc.</li> <li>When specifying numeric ranges, use inclusive ranges when possible.</li> </ul> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Automatic Resource Allocation And Deallocation</h2><a id="user-content-automatic-resource-allocation-and-deallocation" class="anchor" aria-label="Permalink: Automatic Resource Allocation And Deallocation" href="#automatic-resource-allocation-and-deallocation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">API objects often are <a href="#Unions">union</a> object containing the following:</p> <ol dir="auto"> <li>One or more fields identifying the <code>Type</code> specific to API object (aka the <code>discriminator</code>).</li> <li>A set of N fields, only one of which should be set at any given time - effectively a union.</li> </ol> <p dir="auto">Controllers operating on the API type often allocate resources based on the <code>Type</code> and/or some additional data provided by user. A canonical example of this is the <code>Service</code> API object where resources such as IPs and network ports will be set in the API object based on <code>Type</code>. When the user does not specify resources, they will be allocated, and when the user specifies exact value, they will be reserved or rejected.</p> <p dir="auto">When the user chooses to change the <code>discriminator</code> value (e.g., from <code>Type X</code> to <code>Type Y</code>) without changing any other fields then the system should clear the fields that were used to represent <code>Type X</code> in the union along with releasing resources that were attached to <code>Type X</code>. This should automatically happen irrespective of how these values and resources were allocated (i.e., reserved by the user or automatically allocated by the system. A concrete example of this is again <code>Service</code> API. The system allocates resources such as <code>NodePorts</code> and <code>ClusterIPs</code> and automatically fill in the fields that represent them in case of the service is of type <code>NodePort</code> or <code>ClusterIP</code> (<code>discriminator</code> values). These resources and the fields representing them are automatically cleared when the users changes service type to <code>ExternalName</code> where these resources and field values no longer apply.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Representing Allocated Values</h2><a id="user-content-representing-allocated-values" class="anchor" aria-label="Permalink: Representing Allocated Values" href="#representing-allocated-values"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Many API types include values that are allocated on behalf of the user from some larger space (e.g. IP addresses from a range, or storage bucket names). These allocations are usually driven by controllers asynchronously to the user's API operations. Sometimes the user can request a specific value and a controller must confirm or reject that request. There are many examples of this in Kubernetes, and there a handful of patterns used to represent it.</p> <p dir="auto">The common theme among all of these is that the system should not trust users with such fields, and must verify or otherwise confirm such requests before using them.</p> <p dir="auto">Some examples:</p> <ul dir="auto"> <li>Service <code>clusterIP</code>: Users may request a specific IP in <code>spec</code> or will be allocated one (in the same <code>spec</code> field). If a specific IP is requested, the apiserver will either confirm that IP is available or, failing that, will reject the API operation synchronously (rare). Consumers read the result from <code>spec</code>. This is safe because the value is either valid or it is never stored.</li> <li>Service <code>loadBalancerIP</code>: Users may request a specific IP in <code>spec</code> or will be allocated one which is reported in <code>status</code>. If a specific IP is requested, the LB controller will either ensure that IP is available or report failure asynchronously. Consumers read the result from <code>status</code>. This is safe because most users do not have acces to write to <code>status</code>.</li> <li>PersistentVolumeClaims: Users may request a specific PersistentVolume in <code>spec</code> or will be allocated one (in the same <code>spec</code> field). If a specific PV is requested, the volume controller will either ensure that the volume is available or report failure asynchronously. Consumers read the result by examining both the PVC and the PV. This is more complicated than the others because the <code>spec</code> value is stored before being confirmed, which could (hypothetically, thanks to extra checking) lead to a user accessing someone else's PV.</li> <li>VolumeSnapshots: Users may request a particular source to be snaphotted in <code>spec</code>. The details of the resulting snapshot is reflected in <code>status</code>.</li> </ul> <p dir="auto">A counter-example:</p> <ul dir="auto"> <li>Service <code>externalIPs</code>: Users must specify one or more specific IPs in <code>spec</code>. The system cannot easily verify those IPs (by their definition, they are external). Consumers read the result from <code>spec</code>. This is UNSAFE and has caused problems with untrusted users.</li> </ul> <p dir="auto">In the past, API conventions dictated that <code>status</code> fields always come from observation, which made some of these cases more complicated than necessary. The conventions have been updated to allow <code>status</code> to hold such allocated values. This is not a one-size-fits-all solution, though.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">When to use a <code>spec</code> field</h3><a id="user-content-when-to-use-a-spec-field" class="anchor" aria-label="Permalink: When to use a spec field" href="#when-to-use-a-spec-field"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">New APIs should almost never do this. Instead, they should use <code>status</code>. PersistentVolumes might have been simpler if we had done this.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">When to use a <code>status</code> field</h3><a id="user-content-when-to-use-a-status-field" class="anchor" aria-label="Permalink: When to use a status field" href="#when-to-use-a-status-field"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Storing such values in <code>status</code> is the easiest and most straight-forward pattern. This is appropriate when:</p> <ul dir="auto"> <li>the allocated value is highly coupled to the rest of the object (e.g. pod resource allocations)</li> <li>the allocated value is always or almost always needed (i.e. most instances of this type will have a value)</li> <li>the schema and controller are known a priori (i.e. it's not an extension)</li> <li>it is "safe" to allow the controller(s) to write to <code>status</code> (i.e. there's low risk of them causing problems via other <code>status</code> fields).</li> </ul> <p dir="auto">Consumers of such values can look at the <code>status</code> field for the "final" value or an error or condition indicating why the allocation could not be performed.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Sequencing operations</h4><a id="user-content-sequencing-operations" class="anchor" aria-label="Permalink: Sequencing operations" href="#sequencing-operations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Since almost everything is happening asynchronously to almost everything else, controller implementations should take care around the ordering of operations. For example, whether the controller updates a <code>status</code> field before or after it actuates a change depends on what guarantees need to be made to observers of the system. In some cases, writing to a <code>status</code> field represents an acknowledgement or acceptance of a <code>spec</code> value, and it is OK to write it before actuation. However, if it would be problematic for a client to observe the <code>status</code> value before it is actuated then the controller must actuate first and update <code>status</code> afterward. In some rarer cases, controllers will need to acknowledge, then actuate, then update to a "final" value.</p> <p dir="auto">Controllers must take care to consider how a <code>status</code> field will be handled in the case of interrupted control loops (e.g. controller crash and restart), and must act idempotently and consistently. This is particularly important when using an informer-fed cache, which might not be updated with recent writes. Using a resourceVersion precondition to detect the "conflict" is the common pattern in this case. See <a href="http://issue.k8s.io/105199" rel="nofollow">this issue</a> for an example.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">When to use a different type</h3><a id="user-content-when-to-use-a-different-type" class="anchor" aria-label="Permalink: When to use a different type" href="#when-to-use-a-different-type"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Storing allocated values in a different type is more complicated but also more flexible. This is most appropriate when:</p> <ul dir="auto"> <li>the allocated value is optional (i.e. many instances of this type will not have a value at all)</li> <li>the schema and controller are not known a priori (i.e. it's an extension)</li> <li>the schema is sufficiently complicated (i.e. it doesn't make sense to burden the main type with it)</li> <li>access control for this type demands finer granularity than "all of status"</li> <li>the lifecycle of the allocated value is different than the lifecycle of the allocation holder</li> </ul> <p dir="auto">Services and Endpoints could be considered a form of this pattern, as could PersistentVolumes and PersistentVolumeClaims.</p> <p dir="auto">When using this pattern, you must account for lifecycle of the allocated objects (who cleans them up and when) as well as the "linkage" between them and the main type (often using the same name, an object-ref field, or a selector).</p> <p dir="auto">There will always be some cases which could follow either path, and these will need human evaluation to decide. For example, Service <code>clusterIP</code> is highly coupled to the rest of Service and most instances use it. But it also is strictly optional and has an increasingly complicated schema of related fields. An argument could be made for either path.</p> </article></div><button hidden=""></button></section></div></div></div> <!-- --> <!-- --> </div></div></div><div class="Box-sc-g0xbh4-0"></div></div></div></div></div><div id="find-result-marks-container" class="Box-sc-g0xbh4-0 cCoXib"></div><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button></div> <!-- --> <!-- --> <script type="application/json" id="__PRIMER_DATA_:R0:__">{"resolvedServerColorMode":"day"}</script></div> </react-app> </turbo-frame> </div> </turbo-frame> </main> </div> </div> <footer class="footer pt-8 pb-6 f6 color-fg-muted p-responsive" role="contentinfo" > <h2 class='sr-only'>Footer</h2> <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap"> <div class="d-flex flex-items-center flex-shrink-0 mx-2"> <a aria-label="Homepage" title="GitHub" class="footer-octicon mr-2" href="https://github.com"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z"></path> </svg> </a> <span> &copy; 2025 GitHub,&nbsp;Inc. </span> </div> <nav aria-label="Footer"> <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3> <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading"> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a> </li> <li class="mx-2" > <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}" > Manage cookies </button> </cookie-consent-link> </li> <li class="mx-2"> <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}" > Do not share my personal information </button> </cookie-consent-link> </li> </ul> </nav> </div> </footer> <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999" data-initial-cookie-consent-allowed="" data-cookie-consent-required="false"></ghcc-consent> <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> You can’t perform that action at this time. </div> <template id="site-details-dialog"> <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open> <summary role="button" aria-label="Close dialog"></summary> <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal"> <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div class="octocat-spinner my-6 js-details-dialog-spinner"></div> </details-dialog> </details> </template> <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;"> <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;"> </div> </div> <template id="snippet-clipboard-copy-button"> <div class="zeroclipboard-container position-absolute right-0 top-0"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> <template id="snippet-clipboard-copy-button-unpositioned"> <div class="zeroclipboard-container"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> </div> <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div> <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10