sigs.k8s.io/cluster-api@v1.7.1/docs/proposals/20200506-conditions.md (about) 1 --- 2 title: Conditions 3 authors: 4 - "@fabriziopandini" 5 reviewers: 6 - "@vincepri" 7 - "@ncdc" 8 creation-date: 2020-05-06 9 last-updated: 2020-05-20 10 status: implementable 11 see-also: 12 replaces: 13 superseded-by: 14 --- 15 16 # Conditions - Cluster status at glance 17 18 ## Table of Contents 19 20 <!-- START doctoc generated TOC please keep comment here to allow auto update --> 21 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 22 23 - [Glossary](#glossary) 24 - [Summary](#summary) 25 - [Motivation](#motivation) 26 - [Goals](#goals) 27 - [Non-Goals/Future Work](#non-goalsfuture-work) 28 - [Proposal](#proposal) 29 - [User Stories](#user-stories) 30 - [Story 1](#story-1) 31 - [Story 2](#story-2) 32 - [Story 3](#story-3) 33 - [Story 4](#story-4) 34 - [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints) 35 - [Data Model Changes](#data-model-changes) 36 - [Constraints](#constraints) 37 - [Condition semantic](#condition-semantic) 38 - [The Ready condition](#the-ready-condition) 39 - [Controller changes](#controller-changes) 40 - [The cluster provisioning workflow](#the-cluster-provisioning-workflow) 41 - [The `ClusterInfrastructureReady` condition](#the-clusterinfrastructureready-condition) 42 - [The cluster’s `ControlPlaneReady` condition](#the-clusters-controlplaneready-condition) 43 - [The cluster’s `WorkersReady` condition](#the-clusters-workersready-condition) 44 - [The control plane upgrade workflow](#the-control-plane-upgrade-workflow) 45 - [Risks and Mitigations](#risks-and-mitigations) 46 - [Alternatives](#alternatives) 47 - [Kubernetes Conditions](#kubernetes-conditions) 48 - [Status field](#status-field) 49 - [Upgrade Strategy](#upgrade-strategy) 50 - [Additional Details](#additional-details) 51 - [Test Plan [optional]](#test-plan-optional) 52 - [Graduation Criteria [optional]](#graduation-criteria-optional) 53 - [Version Skew Strategy [optional]](#version-skew-strategy-optional) 54 - [Implementation History](#implementation-history) 55 56 <!-- END doctoc generated TOC please keep comment here to allow auto update --> 57 58 ## Glossary 59 60 Refer to the [Cluster API Book Glossary](https://cluster-api.sigs.k8s.io/reference/glossary.html). 61 62 Condition: The state of an object with regard to its appearance, quality, or working order. 63 64 ## Summary 65 66 In Cluster API a workload cluster is composed of a fair number of Kubernetes objects, and to 67 understand the status of your Cluster you have to jump from one object to another. Or, in the 68 worst case, you have to look at the logs from the Cluster API pods to get more details on why 69 things aren’t working. 70 71 This proposal introduces the concept of “conditions” as a tool designed to provide an “at a glance” 72 view of the status of a cluster, providing immediate answers and fine-grained guidance when 73 investigating issues. 74 75 ## Motivation 76 77 - Cluster API requires a large number of objects to define a workload cluster: Cluster, 78 InfrastructureCluster, KubeadmControlPlane, MachineDeployments, Machines, and so on. 79 Each object carries its own status. Operators need to describe each object individually to 80 determine an overall cluster health summary. 81 - Objects can be tied to each other directly (via object references), or indirectly 82 (via owner references). These dependencies can often require a deep knowledge of the 83 project’s internals and its APIs to investigate issues or problems. 84 - Some objects, like MachineSets or MachineDeployments, are considered a collection of 85 other objects (e.g. MachineSets). Their status is effectively tied to the status of each 86 item in the collection. 87 88 ### Goals 89 90 - To define a data model for the Condition type. 91 - To introduce the first set of conditions on Cluster API core objects (up to a minimal level of 92 detail required for an initial implementation). 93 - To provide flexibility for providers to incrementally adopt this proposal. 94 - To provide flexibility for providers to add, remove, or update their own set of conditions over time. 95 - To provide utilities and libraries for a unified way to work with conditions. 96 97 ### Non-Goals/Future Work 98 99 - To pre-define every possible condition. 100 - To define the exact semantic for every condition introduced in the proposal (this should be done 101 during implementation). 102 - To remove or deprecate `Phase`, `FailureMessage`, and `FailureReason` from Status in v0.3. 103 - To remove or deprecate usage of `Events`. 104 105 ## Proposal 106 107 ### User Stories 108 109 #### Story 1 110 As a developer, as a user, as a tool built on top of Cluster API, I would like to have common types 111 for defining conditions on different Cluster API or provider objects. 112 113 #### Story 2 114 As a user, I would like to quickly understand the current state of my cluster 115 during the initial provisioning workflow. 116 117 #### Story 3 118 As a user, I would like to quickly understand the current state of my cluster 119 during the upgrade workflow. 120 121 #### Story 4 122 As a user, I would like to quickly understand the operational state of my cluster. 123 124 ### Implementation Details/Notes/Constraints 125 126 This proposal aims to be consistent with the target state of conditions in Kubernetes (see [KEP](https://github.com/kubernetes/enhancements/pull/1624)). 127 128 At the same time, we should think that Cluster API presents some specific challenges that are not common 129 to the core Kubernetes objects: 130 131 - Cluster API has a high number of long-running operations, and this makes it crucial for the success of 132 this proposal to introduce a clean way to provide evidence about what is happening during those operations, 133 and not only to show the final state of the operations. 134 - Cluster API has a complex hierarchy of objects, and the informative value of a condition, especially in 135 the core types, is highly correlated to the possibility to collect and summarize meaningful information 136 from the underlying hierarchy of objects. 137 - Cluster API defines a set of core objects and extension points (e.g. bootstrap, control plane and infrastructure). 138 Extension points are defined by a set of contracts, which each provider adheres to. To provide a great user 139 experience, core and provider contracts should be extended to allow for better coordination and visibility 140 based on conditions. 141 142 143 This proposal consists of three parts: 144 145 - Data model changes. 146 - Constraints/design principles for implementing conditions in Cluster API- 147 - Use case driven examples of how conditions could improve observability on Cluster API. 148 149 #### Data Model Changes 150 151 In this section we outline the proposed API additions. 152 153 All the changes can be implemented in the v0.3.x timeframe (no breaking changes, only additions). 154 155 Following types should be defined in Cluster API / v1alpha3 api. 156 157 ```golang 158 // ConditionType is a valid value for Condition.Type. 159 type ConditionType string 160 161 // ConditionSeverity expresses the severity of a Condition Type failing. 162 type ConditionSeverity string 163 164 const ( 165 // ConditionSeverityError specifies that a failure of a condition type 166 // should be viewed as an error. 167 ConditionSeverityError ConditionSeverity = "Error" 168 169 // ConditionSeverityWarning specifies that a failure of a condition type 170 // should be viewed as a warning, but that things could still work. 171 ConditionSeverityWarning ConditionSeverity = "Warning" 172 173 // ConditionSeverityInfo specifies that a failure of a condition type 174 // should be viewed as purely informational, and that things could still work. 175 ConditionSeverityInfo ConditionSeverity = "Info" 176 177 // ConditionSeverityNone should apply only if the condition is in state "True". 178 // As ConditionSeverityNone is the default for conditions we use the empty string (coupled with omitempty) 179 ConditionSeverityNone ConditionSeverity = "" 180 ) 181 182 // Condition defines an extension to status (i.e. an observation) of a Cluster API resource. 183 type Condition struct { 184 // Type of condition. 185 Type ConditionType `json:"type" description:"type of status condition"` 186 187 // Status of the condition, one of True, False, Unknown. 188 Status corev1.ConditionStatus `json:"status"` 189 190 // Severity with which to treat failures of this type of condition. 191 // When this is not specified, it defaults to Error. 192 // +optional 193 Severity ConditionSeverity `json:"severity,omitempty"` 194 195 // LastTransitionTime is the last time the condition transitioned from one status to another. 196 LastTransitionTime metav1.Time `json:"lastTransitionTime"` 197 198 // The reason for the condition's last transition. 199 // Reasons should be CamelCase. 200 // +optional 201 Reason string `json:"reason,omitempty" description:"one-word CamelCase reason for the condition's last transition"` 202 203 // A human readable message indicating details about the transition. 204 // +optional 205 Message string `json:"message,omitempty" description:"human-readable message indicating details about last transition"` 206 } 207 208 // Conditions define an extension to status (i.e. an observation) of a Cluster API resource. 209 type Conditions []Condition 210 ``` 211 212 Every Cluster API resource except data-only objects which aren't reconciled (i.e. `KubeadmConfigTemplate`) 213 SHOULD have conditions field in the status struct. e.g. 214 215 ```golang 216 // ClusterStatus represent the status for the Cluster object 217 type ClusterStatus struct { 218 ... 219 // Conditions define a list of readiness conditions for the Cluster object 220 Conditions Conditions `json:"conditions,omitempty" 221 } 222 ``` 223 224 Each Cluster API resource SHOULD define its own set of condition types, e.g. 225 226 ```golang 227 // ConditionTypes for the cluster object 228 const ( 229 ClusterInfrastructureReady ConditionType = "ClusterInfrastructureReady" 230 231 ... 232 ) 233 ``` 234 235 Condition types MUST have a consistent polarity (i.e. "True = good"); 236 237 Condition types SHOULD have one of the following suffix: 238 239 - `Ready`, for resources which represent an ongoing status, like `ControlplaneReady` or `MachineDeploymentsReady`. 240 - `Succeeded`, for resources which run-to-completion, e.g. `CreateVPCSucceeded` 241 242 When the above suffix are not adequate for a specific condition type, other suffix _with positive meaning_ COULD be used 243 (e.g. `Completed`, `Healthy`); however, it is recommended to balance this flexibility with the objective to provide 244 a consistent condition naming across all the Cluster API objects. 245 246 The `Severity` field MUST be set only when `Status=False` and it is designed to provide a standard classification 247 of possible conditions failure `Reason`. 248 249 Please note that the combination of `Reason` and `Severity` gives different meaning to a condition failure 250 allowing to detect when a long-running task is still ongoing: 251 252 ``` 253 ControlPlaneReady=False, Reason=ScalingUp, Severity=Info 254 ``` 255 256 In other cases, the combination of `Reason` and `Severity` allows to detect when a failure is due to a catastrophic 257 error or to other events that are transient or can be eventually remediated by a user intervention 258 259 ``` 260 MachineReady=False, Reason=MachineNotHealthy, Severity=Error 261 MachineReady=False, Reason=MachineUnderProbation, Severity=Warning 262 AWSMachineReady=False, Reason=SSHKeyMissing, Severity=Warning 263 ``` 264 265 A more contextualized example/explanation about the Severity field can be found in the 266 “Cluster provisioning” example later on in this document. 267 268 #### Constraints 269 In order to ensure a consistent implementation of conditions across all the Cluster API components 270 the following constraints/design principles MUST be applied: 271 272 ##### Condition semantic 273 274 - Condition types in Cluster API core objects MUST be provider agnostic. 275 - Condition types in Cluster API core objects MUST represent the operational state of a component 276 in the cluster, where the operational state is when the component is ready to serve application workloads. It should be avoided to represent only the infrastructure/provision part of the component's lifecycle. 277 - Condition types in Cluster API provider-specific objects COULD be used for surfacing more 278 granular/internal details about provisioning, but always with a user driven perspective (conditions != debug). 279 - Operations like upgrades, scaling-up, or scaling-down, even if orchestrated in a non-disruptive fashion, 280 MUST be considered as a deviation from the normal operational state of the cluster, and the operator 281 should be always informed when those changes are happening. 282 e.g. There should be a condition with Severity=Warning. 283 284 ##### The Ready condition 285 286 - A `Ready` condition SHOULD be provided at object level to represent _the overall_ operational state of 287 the component (NB. a more contextualized example/explanation of the Ready conditions can be found 288 in the “Cluster provisioning” example later on in this document). 289 - The `Ready` condition MUST be based on the summary of more detailed conditions existing on the same 290 object, if defined. 291 e.g. `AWSCluster.Status.Conditions[Ready]` condition should be the summary of `VPCReady`, `SubnetsReady`, 292 `InternetGatewaysReady` conditions. 293 - Detailed conditions at object level COULD be based on `Ready` conditions gathered from the dependent 294 objects. e.g. 295 - `Cluster.Status.Conditions[ClusterInfrastructureReady]` is a condition based on infrastructure 296 cluster state, e.g. `AWSCluster.Status.Conditions[Ready]`. 297 - `KubeadmControlPlane.Status.Conditions[MachinesReady]` is a condition based on the aggregation 298 of the underlying `Machines.Status.Conditions[Ready]` conditions. 299 - A corollary of the above set of constraints is that an object SHOULD NEVER be in status `Ready=True` 300 if one of the object's conditions are `false` or if one of the object dependents is in status `Ready=False`. 301 302 ##### Controller changes 303 304 - A controller MUST only evaluate Conditions based on the object it’s reconciling and its directly-referenced 305 objects (dependents). 306 - If the dependents objects are not exposing a `Ready` condition, the summary 307 condition MUST NOT be generated and error MUST NOT be raised; please note that this approach (silently fail), 308 is explicitly designed to allow an incremental implementation of conditions across providers; however, 309 we are expecting this will change in the future. 310 - In order to support an easy and consistent implementation of all the above constraints across all 311 Cluster API components, all the controller MUST use a new set of utilities implemented in Cluster API for: 312 - Summarizing a list of conditions into another condition on the same object 313 - Mirroring a condition from an object to another. 314 - Aggregating a condition from a set of dependents objects. 315 316 #### The cluster provisioning workflow 317 Let’s consider the following timeline representing the workflow for the initial provisioning of a 318 Cluster with ClusterAPI: 319 320  321 322 Conditions are expected to provide a simple and intuitive view of where a Cluster is with respect 323 to this timeline. 324 325 In order to do so, `Cluster.Status.Conditions` should have: 326 327 - A condition of type `ClusterInfrastructureReady` that should provide an observation point on the 328 operational state of the cluster infrastructure. 329 - A condition of type `ControlPlaneReady` that should provide an observation point on the operational 330 state of the cluster control plane. 331 - A condition of type `WorkersReady` that should provide an observation point on the operational state 332 of the workers nodes. 333 334 ##### The `ClusterInfrastructureReady` condition 335 In order to understand how `ClusterInfrastructureReady` condition can be, let’s take AWS as an example 336 of how the cluster infrastructure process can be: 337 338 - Provision Network 339 - Provision VPC 340 - Provision Subnets 341 - Provision InternetGateways 342 - ProvisionNatGateways 343 - Provision RouteTables 344 - Provision SecurityGroups 345 - Provision Bastion Host 346 - Etc. 347 348 Without getting into further details, clearly provisioning an operational cluster infrastructure can 349 be fairly complex, so we would expect to have in `AwsCluster.Status.Conditions` a set condition types 350 providing observation points for all the above steps, e.g. `VPCReady`, `SubnetsReady`, 351 `InternetGatewaysReady`, etc. 352 353 For all the above conditions `Status=True` corresponds to the final state when the resource is 354 provisioned and fully operational (same polarity); it is also important to notice that the elapsed 355 time when those conditions have `Status=False` can be fairly long, so it is crucial to introduce 356 a clean way to provide evidence about what is happening during those phases, e.g. 357 358 - The provisioning is just proceeding (info) 359 - The provisioning is not completed yet, but it is taking longer than expected (warning) 360 - A recoverable error occurred during provisioning and someone/something should take action (warning) 361 - A catastrophic error occurred (error) 362 - The provisioning is completed, but for any reason, the resource is not operational (error) 363 364 This can be achieved by using different `Reason` and `Message` values, but this alone is not ideal, because, 365 in order to understand the implications of each `Reason` code (is it info, a warning, or an error?), 366 it might require a deep knowledge or provider internals; additionally, this forces condition consumers to 367 depend on the `Reason` code enumeration, and this can lead to brittle solutions. 368 369 This problem was addressed by the introduction of the `Severity` field, which provides an explicit 370 classification of `Reason` code, so the users or machines can immediately understand the current situation 371 and act accordingly. 372 373 But, while having many provider-specific conditions in `AwsCluster.Status.Conditions` is definitely a 374 remarkable improvement, at the same time this does not help in creating a consistent experience 375 across providers, and it does not solve the problem of having a simple and intuitive view of the cluster 376 infrastructure operational status in `Cluster.Status.Conditions`. 377 378 In order to solve this problem, the proposed solution is to: 379 380 Introduce a `Ready` condition in `AwsCluster.Status.Conditions` that summarizes _the overall state_ 381 of the current operational status for a cluster infrastructure for AWS. 382 383 Make the `ClusterInfrastructureReady` condition in `Cluster.Status.Conditions` to mirror the above 384 one, or generalizing, to mirror the Ready condition from the infrastructure cluster object. 385 386 Both actions can be generalized and implemented in utility in CAPI; as a working assumption, e.g. 387 the utility that generates summary of a list of conditions should apply the following rules: 388 - Errors MUST surface immediately. 389 - If there are no errors, Warnings MUST surface immediately. 390 - The operation progress SHOULD be expressed in the form of step completed vs total steps to execute 391 (details or possible alternatives TBD). 392 393 ##### The cluster’s `ControlPlaneReady` condition 394 395 The condition of type `Cluster.Status.ControlPlaneReady` should provide an observation point on the 396 operational state of the cluster control plane. 397 398 In order to get this condition in place, we are re-applying the same design patterns defined in the 399 previous paragraph and re-using the "Summarize" and the "Mirror" strategy across the hierarchy of 400 objects that defines the cluster control plane. Below the description of all the required steps: 401 402 A set of provider-specific conditions should be created in `AwsMachine.Status.Conditions`, e.g. 403 `InstanceReady`, `SecurityGroupsReady`, `LBAttachemenReady`, `BootstrapDataSecretDeletionSuccceded` 404 (the other infrastructure providers are expected to implement different conditions at this level) 405 406 A summary of the operational state of the machine infrastructure should be generated in 407 `AwsMachine.Status.Conditions[Ready]`; this condition will be mirrored into 408 `Machine.Status.Conditions[InfrastructureReady]`. 409 410 A set of additional `Machine.Status.Conditions` should be created in order to provide an 411 observation point on the operational state of kubeadm control-plane machine components like 412 e.g. `EtcdReady`, `ApiServerPodReady`, etc. (the other control plane providers are expected to 413 implement different conditions at this level) 414 415 A summary of the operational state of the control plane machine should be generated into 416 `Machine.Status.Conditions[Ready]`; the aggregation of all the machine’s Ready conditions will 417 be mirrored into `KubeadmControlPlane.Status.Conditions[MachinesReady]`. 418 419 A set of additional `KubeadmControlPlane.Status.Conditions` will be created in order 420 to provide an observation point on the operational state of the overall kubeadm control-plane 421 specific processes, like e.g. `ScalingUpSuccedeed`, `ScalingDownSuccedeed`, `MachineRemediationSuccedeed`. 422 423 A summary of the operational state of the entire control plane should be generated into 424 `KubeadmControlPlane.Status.Conditions[Ready]`; this condition will be mirrored into 425 `Cluster.Status.Conditions[ControlPlaneReady]`. 426 427 ##### The cluster’s `WorkersReady` condition 428 429 The Cluster condition `Cluster.Status.WorkersReady` should provide an observation point on 430 the operational state of all workers nodes (incl. Machines, MachineDeployments, MachineSets). 431 432 This can be achieved using the same design patterns defined in the previous paragraph 433 and re-using the "Summarize" and the "Mirror" strategy; however, in this case, the implementation should 434 consider that a cluster can have many MachineDeployments, MachinePools, etc. 435 436 Considering the complexity and to wait for more in-depth analysis and use-cases, the implementation 437 of this Condition is deferred until a later stage. 438 439 ### The control plane upgrade workflow 440 441 To further validate the above design let’s consider another timeline representing the upgrade of a 442 control plane: 443 444  445 446 Also in this case, we expect a simple and intuitive view of where a Cluster is with respect to this 447 timeline, and we expect this should be provided by the condition of type `ControlPlaneReady` 448 introduced in the previous paragraphs. 449 450 However, in order to address the specific use case, the following conditions should be added 451 to `KubeadmControlPlane.Status.Conditions`: `MachinesUpgradeSuccedeed`, `KubeProxyUpgradeSucceded`, 452 `CoreDNSUpgradeSucceded`. Those conditions represent a “run-to-completion” task, and since all of 453 them are related to the same upgrade process, we are assuming to reset those conditions every 454 time an upgrade starts. 455 456 Then, those new conditions will be then captured by the summary in `KubeadmControlPlane.Status.Conditions[Ready]` 457 and be reflected to `Cluster.Status.Conditions[ControlPlaneReady]`. 458 459 However, please note that during upgrades, some rules that are been used to evaluate the 460 operational state of a control plane should be temporary changed e.g. during upgrades: 461 462 - It is acceptable to have a number of replicas higher than the desired number of replicas 463 - It is acceptable that one of the controlled machines is not fully operational while being provisioned. 464 - It is acceptable that one of the controlled machines is becoming not operational while being deleted. 465 466 During the implementation phase, we will consider if to treat such exceptions as a special case or if to 467 enhance the condition utilities to handle those situations in a generalized way. 468 469 ### Risks and Mitigations 470 471 - Risk: This proposal aims to be consistent with the target state of conditions in Kubernetes, but this 472 is still under definition (see [KEP](https://github.com/kubernetes/enhancements/pull/1624)). 473 - Mitigation: Periodically re-evaluate this proposal vs the Kubernetes KEP. 474 475 - Risk: Cluster API presents some specific challenges that are not common to the core Kubernetes objects. 476 - Mitigation: To allow a minimal set of carefully evaluated differences between Cluster API and Kubernetes 477 conditions types. 478 - Mitigation: To define constraints and to provide utilities for dealing with the Cluster API object hierarchy. 479 480 - Risk: This proposal allows for implementing conditions in incremental fashion, and this makes it complex 481 to ensure a consistent approach across all objects. 482 - Mitigation: Ensure all the implementations comply with the defined set of constraints/design principles. 483 484 - Risk: Having a consistent polarity ensures a simple and clear contract with the consumers, and it allows 485 processing conditions in a simple and consistent way without being forced to implement specific logic 486 for each condition type. However, we are aware about the fact that enforcing of consistent polarity (truthy) 487 combined with the usage of recommended suffix for condition types can lead to verbal contortions to express 488 conditions, especially in case of conditions designed to signal problems or in case of conditions 489 that might exist or not. 490 - Mitigation: We are relaxing the rule about recommended suffix and allowing usage of custom suffix. 491 - Mitigation: We are recommending the condition adhere to the design principle to express the operational state 492 of the component, and this should help in avoiding conditions name to surface internal implementation details. 493 - Mitigation: We should recommend condition implementers to clearly document the meaning of Unknown state, because as 494 discussed also in the recent [Kubernetes KEP about standardizing conditions](https://github.com/kubernetes/enhancements/pull/1624#pullrequestreview-388777427), 495 _"Unknown" is a fact about the writer of the condition, and not a claim about the object_. 496 - Mitigation: We should recommend developers of code relying on conditions to treat Unknown as a separated state vs 497 assimilating it to True or False, because this can vary case by case and generate confusion in readers. 498 499 As a final consideration about the risk related to using a consistent polarity, it is important to notice that a 500 consistent polarity ensure a clear meaning for True or o False states, which is already an improvement vs having 501 different interpretations for all the three possible condition states. 502 503 ## Alternatives 504 505 ### Kubernetes Conditions 506 507 While designing this proposal it was considered how Kubernetes APIs implements `.status.conditions` in different 508 objects, i.e. 509 510 Pods have a consistent set of conditions with positive polarity 511 512 ``` 513 Type Status 514 Initialized True 515 Ready True 516 ContainersReady True 517 PodScheduled True 518 ``` 519 520 Nodes instead have a mix of negative and positive polarity conditions 521 522 ``` 523 Type Status 524 MemoryPressure False 525 DiskPressure False 526 PIDPressure False 527 Ready True 528 ``` 529 530 Not only the polarity, but also the schema of condition types slightly changes between different types, and in 531 order to fix this, there is a [KEP](https://github.com/kubernetes/enhancements/pull/1624) that is trying to 532 introduce a common Conditions type, as the first step for convergence about conditions usages and conditions 533 types in Kubernetes. 534 535 This proposal is moving along the same lines of the Kubernetes KEP, with the following small differences 536 as of to day. 537 538 - In K8s the `Type` field is a string, while in this proposal is a string alias so we can enforce the 539 definition of a well-defined set of `ConditionType` constants. 540 - In K8s there is an `ObservedGeneration` field, while in this proposal not. 541 - In this proposal there is an `Severity` field for providing a better classification of the different 542 reasons, while in this K8s not. 543 544 ### Status field 545 546 In Kubernetes during the discussions about conditions one of the points usually discussed is the possibility 547 of using status fields instead of conditions. 548 549 Within the context of this proposal, we are not considering this a viable option, mostly because status 550 fields are object specific and this will fail the objective of creating a consistent UX for the users. 551 552 ## Upgrade Strategy 553 554 NA 555 556 ## Additional Details 557 558 ### Test Plan [optional] 559 560 TBD 561 562 ### Graduation Criteria [optional] 563 564 TBD 565 566 ### Version Skew Strategy [optional] 567 568 NA 569 570 ## Implementation History 571 572 - [ ] 2020-04-27: Compile a Google Doc following the CAEP template 573 - [ ] 2020-05-06: Create CAEP PR