Skip to content

Commit 7790503

Browse files
Merge pull request #536 from njhale/redetect-deployments
feat(csv): detect req and dep change in succeeded/failed phases
2 parents 6c02a7f + f794918 commit 7790503

21 files changed

+2092
-523
lines changed

Documentation/design/architecture.md

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,29 @@ While the OLM Operator is often configured to watch all namespaces, it can also
5454
```
5555
+------------------------------------------------------+
5656
| |
57-
v +--> Succeeded -+
58-
None --> Pending --> InstallReady --> Installing -|
59-
+--> Failed
57+
| +--> Succeeded -+
58+
v | |
59+
None --> Pending --> InstallReady --> Installing -| |
60+
^ +--> Failed <--+
61+
| |
62+
+----------------------------------------------+
6063
\ /
6164
+---------------------------------------------------------------+
6265
|
6366
v
6467
Replacing --> Deleting
6568
```
6669

67-
| Phase | Description |
68-
|------------|------------------------------------------------------------------------------------------------------------------------|
69-
| None | initial phase, once seen by the Operator, it is immediately transitioned to `Pending` |
70-
| Pending | requirements in the CSV are not met, once they are this phase transitions to `Installing` |
71-
| InstallReady | all requirements in the CSV are present, the Operator will begin executing the install strategy |
72-
| Installing | the install strategy is being executed and resources are being created, but not all components are reporting as ready |
73-
| Succeeded | the execution of the Install Strategy was successful; if requirements disappear, this may transition back to `Pending` |
74-
| Failed | upon failed execution of the Install Strategy, the CSV transitions to this terminal phase |
75-
| Replacing | a newer CSV that replaces this one has been discovered in the cluster. This status means the CSV is marked for GC |
76-
| Deleting | the GC loop has determined this CSV is safe to delete from the cluster. It will disappear soon. |
70+
| Phase | Description |
71+
|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
72+
| None | initial phase, once seen by the Operator, it is immediately transitioned to `Pending` |
73+
| Pending | requirements in the CSV are not met, once they are this phase transitions to `Installing` |
74+
| InstallReady | all requirements in the CSV are present, the Operator will begin executing the install strategy |
75+
| Installing | the install strategy is being executed and resources are being created, but not all components are reporting as ready |
76+
| Succeeded | the execution of the Install Strategy was successful; if requirements disappear, or an APIService cert needs to be rotated this may transition back to `Pending`; if an installed component dissapears this may transition to `Failed`|
77+
| Failed | upon failed execution of the Install Strategy, or an installed component dissapears the CSV transitions to this phase; if the component can be recreated by OLM, this may transition to `Pending` |
78+
| Replacing | a newer CSV that replaces this one has been discovered in the cluster. This status means the CSV is marked for GC |
79+
| Deleting | the GC loop has determined this CSV is safe to delete from the cluster. It will disappear soon. |
7780

7881
### Namespace Control Loop
7982

pkg/api/apis/operators/v1alpha1/clusterserviceversion_types.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -182,21 +182,24 @@ const (
182182
type ConditionReason string
183183

184184
const (
185-
CSVReasonRequirementsUnknown ConditionReason = "RequirementsUnknown"
186-
CSVReasonRequirementsNotMet ConditionReason = "RequirementsNotMet"
187-
CSVReasonRequirementsMet ConditionReason = "AllRequirementsMet"
188-
CSVReasonOwnerConflict ConditionReason = "OwnerConflict"
189-
CSVReasonComponentFailed ConditionReason = "InstallComponentFailed"
190-
CSVReasonInvalidStrategy ConditionReason = "InvalidInstallStrategy"
191-
CSVReasonWaiting ConditionReason = "InstallWaiting"
192-
CSVReasonInstallSuccessful ConditionReason = "InstallSucceeded"
193-
CSVReasonInstallCheckFailed ConditionReason = "InstallCheckFailed"
194-
CSVReasonComponentUnhealthy ConditionReason = "ComponentUnhealthy"
195-
CSVReasonBeingReplaced ConditionReason = "BeingReplaced"
196-
CSVReasonReplaced ConditionReason = "Replaced"
197-
CSVReasonNeedCertRotation ConditionReason = "NeedCertRotation"
198-
CSVReasonAPIServiceResourceIssue ConditionReason = "APIServiceResourceIssue"
199-
CSVReasonCopied ConditionReason = "Copied"
185+
CSVReasonRequirementsUnknown ConditionReason = "RequirementsUnknown"
186+
CSVReasonRequirementsNotMet ConditionReason = "RequirementsNotMet"
187+
CSVReasonRequirementsMet ConditionReason = "AllRequirementsMet"
188+
CSVReasonOwnerConflict ConditionReason = "OwnerConflict"
189+
CSVReasonComponentFailed ConditionReason = "InstallComponentFailed"
190+
CSVReasonInvalidStrategy ConditionReason = "InvalidInstallStrategy"
191+
CSVReasonWaiting ConditionReason = "InstallWaiting"
192+
CSVReasonInstallSuccessful ConditionReason = "InstallSucceeded"
193+
CSVReasonInstallCheckFailed ConditionReason = "InstallCheckFailed"
194+
CSVReasonComponentUnhealthy ConditionReason = "ComponentUnhealthy"
195+
CSVReasonBeingReplaced ConditionReason = "BeingReplaced"
196+
CSVReasonReplaced ConditionReason = "Replaced"
197+
CSVReasonNeedsReinstall ConditionReason = "NeedsReinstall"
198+
CSVReasonNeedsCertRotation ConditionReason = "NeedsCertRotation"
199+
CSVReasonAPIServiceResourceIssue ConditionReason = "APIServiceResourceIssue"
200+
CSVReasonAPIServiceResourcesNeedReinstall ConditionReason = "APIServiceResourcesNeedReinstall"
201+
CSVReasonAPIServiceInstallFailed ConditionReason = "APIServiceInstallFailed"
202+
CSVReasonCopied ConditionReason = "Copied"
200203
)
201204

202205
// Conditions appear in the status as a record of state transitions on the ClusterServiceVersion
@@ -220,8 +223,20 @@ type ClusterServiceVersionCondition struct {
220223

221224
// OwnsCRD determines whether the current CSV owns a paritcular CRD.
222225
func (csv ClusterServiceVersion) OwnsCRD(name string) bool {
223-
for _, crdDescription := range csv.Spec.CustomResourceDefinitions.Owned {
224-
if crdDescription.Name == name {
226+
for _, desc := range csv.Spec.CustomResourceDefinitions.Owned {
227+
if desc.Name == name {
228+
return true
229+
}
230+
}
231+
232+
return false
233+
}
234+
235+
// OwnsAPIService determines whether the current CSV owns a paritcular APIService.
236+
func (csv ClusterServiceVersion) OwnsAPIService(name string) bool {
237+
for _, desc := range csv.Spec.APIServiceDefinitions.Owned {
238+
apiServiceName := fmt.Sprintf("%s.%s", desc.Version, desc.Group)
239+
if apiServiceName == name {
225240
return true
226241
}
227242
}

pkg/controller/certs/certs.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import (
1515
"time"
1616
)
1717

18-
const (
19-
Organization = "Red Hat, Inc."
20-
)
21-
2218
// KeyPair stores an x509 certificate and its ECDSA private key
2319
type KeyPair struct {
2420
Cert *x509.Certificate
@@ -49,7 +45,7 @@ func (kp *KeyPair) ToPEM() (certPEM []byte, privPEM []byte, err error) {
4945
}
5046

5147
// GenerateCA generates a self-signed CA cert/key pair that expires in expiresIn days
52-
func GenerateCA(notAfter time.Time) (*KeyPair, error) {
48+
func GenerateCA(notAfter time.Time, organization string) (*KeyPair, error) {
5349
notBefore := time.Now()
5450
if notAfter.Before(notBefore) {
5551
return nil, fmt.Errorf("invalid notAfter: %s before %s", notAfter.String(), notBefore.String())
@@ -63,7 +59,7 @@ func GenerateCA(notAfter time.Time) (*KeyPair, error) {
6359
caDetails := &x509.Certificate{
6460
SerialNumber: serial,
6561
Subject: pkix.Name{
66-
Organization: []string{Organization},
62+
Organization: []string{organization},
6763
},
6864
NotBefore: notBefore,
6965
NotAfter: notAfter,
@@ -98,7 +94,7 @@ func GenerateCA(notAfter time.Time) (*KeyPair, error) {
9894
}
9995

10096
// CreateSignedServingPair creates a serving cert/key pair signed by the given ca
101-
func CreateSignedServingPair(notAfter time.Time, ca *KeyPair, hosts []string) (*KeyPair, error) {
97+
func CreateSignedServingPair(notAfter time.Time, organization string, ca *KeyPair, hosts []string) (*KeyPair, error) {
10298
notBefore := time.Now()
10399
if notAfter.Before(notBefore) {
104100
return nil, fmt.Errorf("invalid notAfter: %s before %s", notAfter.String(), notBefore.String())
@@ -112,7 +108,7 @@ func CreateSignedServingPair(notAfter time.Time, ca *KeyPair, hosts []string) (*
112108
certDetails := &x509.Certificate{
113109
SerialNumber: serial,
114110
Subject: pkix.Name{
115-
Organization: []string{Organization},
111+
Organization: []string{organization},
116112
},
117113
NotBefore: notBefore,
118114
NotAfter: notAfter,
@@ -185,8 +181,10 @@ func Active(cert *x509.Certificate) bool {
185181
return active
186182
}
187183

184+
// PEMHash returns a hash of the given PEM encoded cert
188185
type PEMHash func(certPEM []byte) (hash string)
189186

187+
// PEMSHA256 returns the hex encoded SHA 256 hash of the given PEM encoded cert
190188
func PEMSHA256(certPEM []byte) (hash string) {
191189
hasher := sha256.New()
192190
hasher.Write(certPEM)

0 commit comments

Comments
 (0)