Skip to content

Commit

Permalink
feat: enhance supportting for changing parent prj
Browse files Browse the repository at this point in the history
  • Loading branch information
defydahui authored and QianChenglong committed Mar 25, 2020
1 parent 89e286e commit 14040b7
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 116 deletions.
2 changes: 2 additions & 0 deletions api/business/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ type ProjectStatus struct {
CalculatedNamespaces []string
// +optional
CachedSpecClusters ClusterHard
// +optional
CachedParent *string
}

// ProjectPhase defines the phase of project constructor.
Expand Down
258 changes: 152 additions & 106 deletions api/business/v1/generated.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions api/business/v1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions api/business/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ type ProjectStatus struct {
CalculatedNamespaces []string `json:"calculatedNamespaces,omitempty" protobuf:"bytes,5,rep,name=calculatedNamespaces"`
// +optional
CachedSpecClusters ClusterHard `json:"cachedSpecClusters,omitempty" protobuf:"bytes,6,rep,name=cachedSpecClusters,casttype=ClusterHard"`
// +optional
CachedParent *string `json:"cachedParent,omitempty" protobuf:"bytes,7,opt,name=cachedParent"`
}

// ProjectPhase defines the phase of project constructor.
Expand Down
2 changes: 2 additions & 0 deletions api/business/v1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions api/business/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions api/business/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 73 additions & 1 deletion api/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/business/controller/project/project_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ func (s *projectCache) getOrCreate(name string, self *v1.Project) *cachedProject
} else { // For historic data that has no CachedSpecClusters
project.state.Spec.Clusters = self.Spec.Clusters
}
if self.Status.CachedParent != nil {
project.state.Spec.ParentProjectName = *self.Status.CachedParent
} else {
project.state.Spec.ParentProjectName = self.Spec.ParentProjectName
}
}
s.m[name] = project
}
Expand Down
25 changes: 16 additions & 9 deletions pkg/business/controller/project/project_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,16 @@ func (c *Controller) handlePhase(key string, cachedProject *cachedProject, proje
return err
}
}
// Once parentProject has been updated, update project CachedSpecClusters immediately.
if project != nil && !reflect.DeepEqual(project.Spec.Clusters, project.Status.CachedSpecClusters) {
return c.updateCache(project, project.Spec.Clusters)
// Once parentProject has been updated, update project cached status immediately.
if project.Status.CachedParent == nil ||
project.Spec.ParentProjectName != *project.Status.CachedParent ||
!reflect.DeepEqual(project.Spec.Clusters, project.Status.CachedSpecClusters) {
return c.updateCachedStatus(project, project.Spec.Clusters, project.Spec.ParentProjectName)
}
} else if project.Status.CachedParent != nil && project.Spec.ParentProjectName != *project.Status.CachedParent {
return c.updateCachedStatus(project, nil, project.Spec.ParentProjectName)
}

return nil
}

Expand All @@ -346,30 +351,32 @@ func (c *Controller) persistUpdate(project *v1.Project) error {
return err
}

func (c *Controller) updateCache(project *v1.Project, newCache v1.ClusterHard) error {
func (c *Controller) updateCachedStatus(project *v1.Project, newCachedClusters v1.ClusterHard, newCachedParent string) error {
var err error
project.Status.CachedSpecClusters = newCache
project.Status.CachedParent = &newCachedParent
project.Status.CachedSpecClusters = newCachedClusters
for i := 0; i < clientRetryCount; i++ {
_, err = c.client.BusinessV1().Projects().UpdateStatus(project)
if err == nil {
return nil
}
if errors.IsNotFound(err) {
log.Info(fmt.Sprintf("Not updateCache of non-existed project %s", project.ObjectMeta.Name), log.Err(err))
log.Info(fmt.Sprintf("Not updateCachedStatus of non-existed project %s", project.ObjectMeta.Name), log.Err(err))
return nil
}
if errors.IsConflict(err) {
newProject, newErr := c.client.BusinessV1().Projects().Get(project.ObjectMeta.Name, metav1.GetOptions{})
if newErr == nil {
project = newProject
project.Status.CachedSpecClusters = newCache
project.Status.CachedParent = &newCachedParent
project.Status.CachedSpecClusters = newCachedClusters
} else {
log.Warn(fmt.Sprintf("Failed to get project %s", project.ObjectMeta.Name), log.Err(newErr))
}
}
log.Warn(fmt.Sprintf("Failed to updateCache of project %s", project.ObjectMeta.Name), log.Err(err))
log.Warn(fmt.Sprintf("Failed to updateCachedStatus of project %s", project.ObjectMeta.Name), log.Err(err))
time.Sleep(clientRetryInterval)
}
log.Error(fmt.Sprintf("Failed to updateCache of project %s", project.ObjectMeta.Name), log.Err(err))
log.Error(fmt.Sprintf("Failed to updateCachedStatus of project %s", project.ObjectMeta.Name), log.Err(err))
return err
}
6 changes: 6 additions & 0 deletions pkg/business/registry/project/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ func (Strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
} else { // For historic data that has no CachedSpecClusters
project.Status.CachedSpecClusters = oldProject.Spec.Clusters
}

if oldProject.Status.CachedParent != nil {
project.Status.CachedParent = oldProject.Status.CachedParent
} else { // For historic data that has no CachedParent
project.Status.CachedParent = &oldProject.Spec.ParentProjectName
}
}

// NamespaceScoped is false for projects.
Expand Down

0 comments on commit 14040b7

Please sign in to comment.