Coverage for ocp_resources/deployment.py: 0%

61 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-30 10:48 +0200

1# Generated using https://github.com/RedHatQE/openshift-python-wrapper/blob/main/scripts/resource/README.md 

2 

3from typing import Any, Dict, Optional 

4from timeout_sampler import TimeoutSampler, TimeoutWatch 

5 

6from ocp_resources.utils.constants import PROTOCOL_ERROR_EXCEPTION_DICT, TIMEOUT_4MINUTES 

7from ocp_resources.resource import NamespacedResource, MissingRequiredArgumentError 

8 

9 

10class Deployment(NamespacedResource): 

11 """ 

12 Deployment enables declarative updates for Pods and ReplicaSets. 

13 """ 

14 

15 api_group: str = NamespacedResource.ApiGroup.APPS 

16 

17 def __init__( 

18 self, 

19 min_ready_seconds: Optional[int] = None, 

20 paused: Optional[bool] = None, 

21 progress_deadline_seconds: Optional[int] = None, 

22 replicas: Optional[int] = None, 

23 revision_history_limit: Optional[int] = None, 

24 selector: Optional[Dict[str, Any]] = None, 

25 strategy: Optional[Dict[str, Any]] = None, 

26 template: Optional[Dict[str, Any]] = None, 

27 **kwargs: Any, 

28 ) -> None: 

29 """ 

30 Args: 

31 min_ready_seconds (int): Minimum number of seconds for which a newly created pod should be 

32 ready without any of its container crashing, for it to be 

33 considered available. Defaults to 0 (pod will be considered 

34 available as soon as it is ready) 

35 

36 paused (bool): Indicates that the deployment is paused. 

37 

38 progress_deadline_seconds (int): The maximum time in seconds for a deployment to make progress before 

39 it is considered to be failed. The deployment controller will 

40 continue to process failed deployments and a condition with a 

41 ProgressDeadlineExceeded reason will be surfaced in the deployment 

42 status. Note that progress will not be estimated during the time a 

43 deployment is paused. Defaults to 600s. 

44 

45 replicas (int): Number of desired pods. This is a pointer to distinguish between 

46 explicit zero and not specified. Defaults to 1. 

47 

48 revision_history_limit (int): The number of old ReplicaSets to retain to allow rollback. This is a 

49 pointer to distinguish between explicit zero and not specified. 

50 Defaults to 10. 

51 

52 selector (Dict[str, Any]): A label selector is a label query over a set of resources. The result 

53 of matchLabels and matchExpressions are ANDed. An empty label 

54 selector matches all objects. A null label selector matches no 

55 objects. 

56 

57 strategy (Dict[str, Any]): DeploymentStrategy describes how to replace existing pods with new 

58 ones. 

59 

60 template (Dict[str, Any]): PodTemplateSpec describes the data a pod should have when created from 

61 a template 

62 

63 """ 

64 super().__init__(**kwargs) 

65 

66 self.min_ready_seconds = min_ready_seconds 

67 self.paused = paused 

68 self.progress_deadline_seconds = progress_deadline_seconds 

69 self.replicas = replicas 

70 self.revision_history_limit = revision_history_limit 

71 self.selector = selector 

72 self.strategy = strategy 

73 self.template = template 

74 

75 def to_dict(self) -> None: 

76 super().to_dict() 

77 

78 if not self.kind_dict and not self.yaml_file: 

79 if not self.selector: 

80 raise MissingRequiredArgumentError(argument="self.selector") 

81 

82 if not self.template: 

83 raise MissingRequiredArgumentError(argument="self.template") 

84 

85 self.res["spec"] = {} 

86 _spec = self.res["spec"] 

87 

88 _spec["selector"] = self.selector 

89 _spec["template"] = self.template 

90 

91 if self.min_ready_seconds: 

92 _spec["minReadySeconds"] = self.min_ready_seconds 

93 

94 if self.paused is not None: 

95 _spec["paused"] = self.paused 

96 

97 if self.progress_deadline_seconds: 

98 _spec["progressDeadlineSeconds"] = self.progress_deadline_seconds 

99 

100 if self.replicas: 

101 _spec["replicas"] = self.replicas 

102 

103 if self.revision_history_limit: 

104 _spec["revisionHistoryLimit"] = self.revision_history_limit 

105 

106 if self.strategy: 

107 _spec["strategy"] = self.strategy 

108 

109 # End of generated code 

110 

111 def scale_replicas(self, replica_count=int): 

112 """ 

113 Update replicas in deployment. 

114 

115 Args: 

116 replica_count (int): Number of replicas. 

117 

118 Returns: 

119 Deployment is updated successfully 

120 """ 

121 super().to_dict() 

122 self.res.update({"spec": {"replicas": replica_count}}) 

123 

124 self.logger.info(f"Set deployment replicas: {replica_count}") 

125 return self.update(resource_dict=self.res) 

126 

127 def wait_for_replicas(self, deployed: bool = True, timeout: int = TIMEOUT_4MINUTES): 

128 """ 

129 Wait until all replicas are updated. 

130 

131 Args: 

132 deployed (bool): True for replicas deployed, False for no replicas. 

133 timeout (int): Time to wait for the deployment. 

134 

135 Raises: 

136 TimeoutExpiredError: If not availableReplicas is equal to replicas. 

137 """ 

138 self.logger.info(f"Wait for {self.kind} {self.name} to be deployed: {deployed}") 

139 

140 timeout_watcher = TimeoutWatch(timeout=timeout) 

141 for sample in TimeoutSampler( 

142 wait_timeout=timeout, 

143 sleep=1, 

144 func=lambda: self.exists, 

145 ): 

146 if sample: 

147 break 

148 

149 samples = TimeoutSampler( 

150 wait_timeout=timeout_watcher.remaining_time(), 

151 sleep=1, 

152 exceptions_dict=PROTOCOL_ERROR_EXCEPTION_DICT, 

153 func=lambda: self.instance, 

154 ) 

155 for sample in samples: 

156 if sample: 

157 status = sample.status 

158 

159 spec_replicas = sample.spec.replicas 

160 total_replicas = status.replicas or 0 

161 updated_replicas = status.updatedReplicas or 0 

162 available_replicas = status.availableReplicas or 0 

163 ready_replicas = status.readyReplicas or 0 

164 

165 if ( 

166 (deployed and spec_replicas) 

167 and spec_replicas == updated_replicas == available_replicas == ready_replicas 

168 ) or not (deployed or spec_replicas or total_replicas): 

169 return