diff --git a/artifacts/deploy/prediction.crane.io_clusternodepredictions.yaml b/artifacts/deploy/prediction.crane.io_clusternodepredictions.yaml index c70c3d8..1680e9e 100644 --- a/artifacts/deploy/prediction.crane.io_clusternodepredictions.yaml +++ b/artifacts/deploy/prediction.crane.io_clusternodepredictions.yaml @@ -1,11 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.18.0 name: clusternodepredictions.prediction.crane.io spec: group: prediction.crane.io @@ -21,18 +19,24 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: ClusterNodePrediction must be created in crane root namespace + description: |- + ClusterNodePrediction must be created in crane root namespace as TimeSeriesPrediction is a namespaced object now properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -143,6 +147,41 @@ spec: targetUtilization: type: string type: object + sp: + description: SP is an algorithm which use exponential + time decay histogram, it can predict a 24 reasonable + value according your history time series + properties: + aggregated: + type: boolean + histogram: + properties: + bucketSize: + type: string + bucketSizeGrowthRatio: + type: string + epsilon: + type: string + firstBucketSize: + type: string + halfLife: + type: string + maxValue: + type: string + type: object + historyLength: + type: string + marginFraction: + type: string + minSampleWeight: + type: string + percentile: + type: string + sampleInterval: + type: string + targetUtilization: + type: string + type: object type: object expressionQuery: description: ExpressionQuery is a query with a DSL-style @@ -154,19 +193,18 @@ spec: type: string type: object metricQuery: - description: following QueryExpressions depend on your - crane system data source configured when the system - start. if you use different sources with your system - start params, it is not valid. MetricQuery is a query - against a metric with a set of conditions + description: |- + following QueryExpressions depend on your crane system data source configured when the system start. + if you use different sources with your system start params, it is not valid. + MetricQuery is a query against a metric with a set of conditions properties: labels: description: QueryConditions is a query condition list. items: - description: QueryCondition is a key, operator, - value triple. E.g. 'namespace = default', 'role - in [Admin, Developer]' + description: |- + QueryCondition is a key, operator, value triple. + E.g. 'namespace = default', 'role in [Admin, Developer]' properties: key: description: Key is the key of the query condition @@ -184,6 +222,8 @@ spec: metricName: description: MetricName is the name of the metric. type: string + required: + - metricName type: object resourceIdentifier: description: ResourceIdentifier is a resource to identify @@ -206,45 +246,50 @@ spec: format: int32 type: integer targetRef: - description: Target is the target referent of time series - prediction. each TimeSeriesPrediction associate with just - only one target ref. all metrics in PredictionMetricConfigurations - is about the TargetRef + description: |- + Target is the target referent of time series prediction. each TimeSeriesPrediction associate with just only one target ref. + all metrics in PredictionMetricConfigurations is about the TargetRef properties: apiVersion: description: API version of the referent. type: string fieldPath: - description: 'If referring to a piece of an object instead - of an entire object, this string should contain a valid - JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container - within a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that - triggered the event) or if no container name is specified - "spec.containers[2]" (container with index 2 in this - pod). This syntax is chosen only to have some well-defined - way of referencing a part of an object. TODO: this design - is not final and this field is subject to change in - the future.' + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. type: string kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ type: string resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency type: string uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids type: string type: object + x-kubernetes-map-type: atomic type: object type: object type: object @@ -252,44 +297,35 @@ spec: properties: conditions: items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + description: Condition contains details for one aspect of the current + state of this API Resource. properties: lastTransitionTime: - description: 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. + description: |- + 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. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: 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. + description: |- + 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. format: int64 minimum: 0 type: integer reason: - description: 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. + description: |- + 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. maxLength: 1024 minLength: 1 @@ -304,10 +340,6 @@ spec: type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -329,9 +361,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/artifacts/deploy/prediction.crane.io_timeseriespredictionrules.yaml b/artifacts/deploy/prediction.crane.io_timeseriespredictionrules.yaml new file mode 100644 index 0000000..57d98d8 --- /dev/null +++ b/artifacts/deploy/prediction.crane.io_timeseriespredictionrules.yaml @@ -0,0 +1,291 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + name: timeseriespredictionrules.prediction.crane.io +spec: + group: prediction.crane.io + names: + kind: TimeSeriesPredictionRule + listKind: TimeSeriesPredictionRuleList + plural: timeseriespredictionrules + shortNames: + - tspr + singular: timeseriespredictionrule + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.runInterval + name: RunInterval + type: string + - description: CreationTimestamp is a timestamp representing the server time when + this object was created. + jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: TimeSeriesPredictionRule represents the configuration of an TimeSeriesPredictionRule + object. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: TimeSeriesPredictionRuleSpec defines resources and runInterval + to recommend + properties: + namespaceSelector: + description: NamespaceSelector indicates resource namespaces to select + from + properties: + any: + description: Select all namespace if true + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + recommenders: + description: List of recommender type to run + items: + description: Recommender referring to the Recommender in RecommendationConfiguration + properties: + config: + additionalProperties: + type: string + description: Override Recommendation configs + type: object + name: + description: Recommender's Name + type: string + required: + - name + type: object + type: array + resourceSelectors: + description: ResourceSelector indicates how to select resources(e.g. + a set of Deployments) for a Recommendation. + items: + description: ResourceSelector describes how the resources will be + selected. + properties: + apiVersion: + description: API version of the resource, e.g. "apps/v1" + type: string + kind: + description: Kind of the resource, e.g. Deployment + type: string + labelSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Name of the resource. + type: string + required: + - kind + type: object + type: array + runInterval: + description: RunInterval between two recommendation + type: string + required: + - namespaceSelector + - recommenders + - resourceSelectors + type: object + status: + description: TimeSeriesPredictionRuleStatus represents the current state + of an TimeSeriesPredictionRule item. + properties: + lastUpdateTime: + description: LastUpdateTime is the last time the status updated. + format: date-time + type: string + recommendations: + description: Recommendations is a list of RecommendationMission that + run parallel. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + lastStartTime: + description: LastStartTime is last time we start a recommendation + mission. + format: date-time + type: string + message: + description: Message presents the running message for this mission + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + recommenderRef: + description: RecommenderRef presents recommender info for recommendation + mission. + properties: + config: + additionalProperties: + type: string + description: Override Recommendation configs + type: object + name: + description: Recommender's Name + type: string + required: + - name + type: object + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + targetRef: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + runNumber: + description: RunNumber is the numbers of runs + format: int32 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/artifacts/deploy/prediction.crane.io_timeseriespredictions.yaml b/artifacts/deploy/prediction.crane.io_timeseriespredictions.yaml index f21839a..457c44c 100644 --- a/artifacts/deploy/prediction.crane.io_timeseriespredictions.yaml +++ b/artifacts/deploy/prediction.crane.io_timeseriespredictions.yaml @@ -1,11 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.18.0 name: timeseriespredictions.prediction.crane.io spec: group: prediction.crane.io @@ -42,14 +40,19 @@ spec: description: TimeSeriesPrediction is a prediction for a time series. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -148,6 +151,41 @@ spec: targetUtilization: type: string type: object + sp: + description: SP is an algorithm which use exponential time + decay histogram, it can predict a 24 reasonable value + according your history time series + properties: + aggregated: + type: boolean + histogram: + properties: + bucketSize: + type: string + bucketSizeGrowthRatio: + type: string + epsilon: + type: string + firstBucketSize: + type: string + halfLife: + type: string + maxValue: + type: string + type: object + historyLength: + type: string + marginFraction: + type: string + minSampleWeight: + type: string + percentile: + type: string + sampleInterval: + type: string + targetUtilization: + type: string + type: object type: object expressionQuery: description: ExpressionQuery is a query with a DSL-style expression, @@ -159,18 +197,17 @@ spec: type: string type: object metricQuery: - description: following QueryExpressions depend on your crane - system data source configured when the system start. if you - use different sources with your system start params, it is - not valid. MetricQuery is a query against a metric with a - set of conditions + description: |- + following QueryExpressions depend on your crane system data source configured when the system start. + if you use different sources with your system start params, it is not valid. + MetricQuery is a query against a metric with a set of conditions properties: labels: description: QueryConditions is a query condition list. items: - description: QueryCondition is a key, operator, value - triple. E.g. 'namespace = default', 'role in [Admin, - Developer]' + description: |- + QueryCondition is a key, operator, value triple. + E.g. 'namespace = default', 'role in [Admin, Developer]' properties: key: description: Key is the key of the query condition @@ -188,6 +225,8 @@ spec: metricName: description: MetricName is the name of the metric. type: string + required: + - metricName type: object resourceIdentifier: description: ResourceIdentifier is a resource to identify the @@ -209,43 +248,50 @@ spec: format: int32 type: integer targetRef: - description: Target is the target referent of time series prediction. - each TimeSeriesPrediction associate with just only one target ref. + description: |- + Target is the target referent of time series prediction. each TimeSeriesPrediction associate with just only one target ref. all metrics in PredictionMetricConfigurations is about the TargetRef properties: apiVersion: description: API version of the referent. type: string fieldPath: - description: 'If referring to a piece of an object instead of - an entire object, this string should contain a valid JSON/Go - field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container within - a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that triggered - the event) or if no container name is specified "spec.containers[2]" - (container with index 2 in this pod). This syntax is chosen - only to have some well-defined way of referencing a part of - an object. TODO: this design is not final and this field is - subject to change in the future.' + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. type: string kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ type: string resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency type: string uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids type: string type: object + x-kubernetes-map-type: atomic type: object status: description: TimeSeriesPredictionStatus is the status of a TimeSeriesPrediction. @@ -253,44 +299,35 @@ spec: conditions: description: Conditions is the condition of TimeSeriesPrediction items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + description: Condition contains details for one aspect of the current + state of this API Resource. properties: lastTransitionTime: - description: 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. + description: |- + 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. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: 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. + description: |- + 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. format: int64 minimum: 0 type: integer reason: - description: 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. + description: |- + 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. maxLength: 1024 minLength: 1 @@ -305,10 +342,6 @@ spec: type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -336,15 +369,14 @@ spec: belong to a metric with a set of labels properties: labels: - description: A collection of Labels that are attached - by monitoring system as metadata for the metrics, which - are known as dimensions. + description: |- + A collection of Labels that are attached by monitoring system as metadata + for the metrics, which are known as dimensions. items: - description: A Label is a Name and Value pair that provides - additional information about the metric. It is metadata - for the metric. For example, Kubernetes pod metrics - always have 'namespace' label that represents which - namespace it belongs to. + description: |- + A Label is a Name and Value pair that provides additional information about the metric. + It is metadata for the metric. For example, Kubernetes pod metrics always have + 'namespace' label that represents which namespace it belongs to. properties: name: type: string @@ -371,9 +403,9 @@ spec: description: Specifies whether the prediction is Ready. type: boolean resourceIdentifier: - description: ResourceIdentifier is a resource to identify the - metric, but now it is just an identifier now. such as cpu, - memory + description: |- + ResourceIdentifier is a resource to identify the metric, but now it is just an identifier now. + such as cpu, memory type: string required: - ready @@ -385,9 +417,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/hack/update-crdgen.sh b/hack/update-crdgen.sh index 334465d..79afe82 100755 --- a/hack/update-crdgen.sh +++ b/hack/update-crdgen.sh @@ -5,7 +5,8 @@ set -o nounset set -o pipefail CONTROLLER_GEN_PKG="sigs.k8s.io/controller-tools/cmd/controller-gen" -CONTROLLER_GEN_VER="v0.7.0" +#CONTROLLER_GEN_VER="v0.7.0" +CONTROLLER_GEN_VER="v0.18.0" source hack/util.sh diff --git a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_prediction_client.go b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_prediction_client.go index 5d919ce..6277b01 100644 --- a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_prediction_client.go +++ b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_prediction_client.go @@ -20,6 +20,10 @@ func (c *FakePredictionV1alpha1) TimeSeriesPredictions(namespace string) v1alpha return &FakeTimeSeriesPredictions{c, namespace} } +func (c *FakePredictionV1alpha1) TimeSeriesPredictionRules() v1alpha1.TimeSeriesPredictionRuleInterface { + return &FakeTimeSeriesPredictionRules{c} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakePredictionV1alpha1) RESTClient() rest.Interface { diff --git a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_timeseriespredictionrule.go b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_timeseriespredictionrule.go new file mode 100644 index 0000000..c5b5459 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/fake/fake_timeseriespredictionrule.go @@ -0,0 +1,117 @@ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/gocrane/api/prediction/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeTimeSeriesPredictionRules implements TimeSeriesPredictionRuleInterface +type FakeTimeSeriesPredictionRules struct { + Fake *FakePredictionV1alpha1 +} + +var timeseriespredictionrulesResource = schema.GroupVersionResource{Group: "prediction.crane.io", Version: "v1alpha1", Resource: "timeseriespredictionrules"} + +var timeseriespredictionrulesKind = schema.GroupVersionKind{Group: "prediction.crane.io", Version: "v1alpha1", Kind: "TimeSeriesPredictionRule"} + +// Get takes name of the timeSeriesPredictionRule, and returns the corresponding timeSeriesPredictionRule object, and an error if there is any. +func (c *FakeTimeSeriesPredictionRules) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(timeseriespredictionrulesResource, name), &v1alpha1.TimeSeriesPredictionRule{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), err +} + +// List takes label and field selectors, and returns the list of TimeSeriesPredictionRules that match those selectors. +func (c *FakeTimeSeriesPredictionRules) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.TimeSeriesPredictionRuleList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(timeseriespredictionrulesResource, timeseriespredictionrulesKind, opts), &v1alpha1.TimeSeriesPredictionRuleList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.TimeSeriesPredictionRuleList{ListMeta: obj.(*v1alpha1.TimeSeriesPredictionRuleList).ListMeta} + for _, item := range obj.(*v1alpha1.TimeSeriesPredictionRuleList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested timeSeriesPredictionRules. +func (c *FakeTimeSeriesPredictionRules) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(timeseriespredictionrulesResource, opts)) +} + +// Create takes the representation of a timeSeriesPredictionRule and creates it. Returns the server's representation of the timeSeriesPredictionRule, and an error, if there is any. +func (c *FakeTimeSeriesPredictionRules) Create(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.CreateOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(timeseriespredictionrulesResource, timeSeriesPredictionRule), &v1alpha1.TimeSeriesPredictionRule{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), err +} + +// Update takes the representation of a timeSeriesPredictionRule and updates it. Returns the server's representation of the timeSeriesPredictionRule, and an error, if there is any. +func (c *FakeTimeSeriesPredictionRules) Update(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(timeseriespredictionrulesResource, timeSeriesPredictionRule), &v1alpha1.TimeSeriesPredictionRule{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeTimeSeriesPredictionRules) UpdateStatus(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (*v1alpha1.TimeSeriesPredictionRule, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(timeseriespredictionrulesResource, "status", timeSeriesPredictionRule), &v1alpha1.TimeSeriesPredictionRule{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), err +} + +// Delete takes name of the timeSeriesPredictionRule and deletes it. Returns an error if one occurs. +func (c *FakeTimeSeriesPredictionRules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteAction(timeseriespredictionrulesResource, name), &v1alpha1.TimeSeriesPredictionRule{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeTimeSeriesPredictionRules) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(timeseriespredictionrulesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.TimeSeriesPredictionRuleList{}) + return err +} + +// Patch applies the patch and returns the patched timeSeriesPredictionRule. +func (c *FakeTimeSeriesPredictionRules) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(timeseriespredictionrulesResource, name, pt, data, subresources...), &v1alpha1.TimeSeriesPredictionRule{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), err +} diff --git a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/generated_expansion.go index e61f1c7..7d8ffdc 100644 --- a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/generated_expansion.go @@ -5,3 +5,5 @@ package v1alpha1 type ClusterNodePredictionExpansion interface{} type TimeSeriesPredictionExpansion interface{} + +type TimeSeriesPredictionRuleExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/prediction_client.go b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/prediction_client.go index b5410dc..b7e19f8 100644 --- a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/prediction_client.go +++ b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/prediction_client.go @@ -12,6 +12,7 @@ type PredictionV1alpha1Interface interface { RESTClient() rest.Interface ClusterNodePredictionsGetter TimeSeriesPredictionsGetter + TimeSeriesPredictionRulesGetter } // PredictionV1alpha1Client is used to interact with features provided by the prediction.crane.io group. @@ -27,6 +28,10 @@ func (c *PredictionV1alpha1Client) TimeSeriesPredictions(namespace string) TimeS return newTimeSeriesPredictions(c, namespace) } +func (c *PredictionV1alpha1Client) TimeSeriesPredictionRules() TimeSeriesPredictionRuleInterface { + return newTimeSeriesPredictionRules(c) +} + // NewForConfig creates a new PredictionV1alpha1Client for the given config. func NewForConfig(c *rest.Config) (*PredictionV1alpha1Client, error) { config := *c diff --git a/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/timeseriespredictionrule.go b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/timeseriespredictionrule.go new file mode 100644 index 0000000..f63a8e5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/prediction/v1alpha1/timeseriespredictionrule.go @@ -0,0 +1,168 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + scheme "github.com/gocrane/api/pkg/generated/clientset/versioned/scheme" + v1alpha1 "github.com/gocrane/api/prediction/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// TimeSeriesPredictionRulesGetter has a method to return a TimeSeriesPredictionRuleInterface. +// A group's client should implement this interface. +type TimeSeriesPredictionRulesGetter interface { + TimeSeriesPredictionRules() TimeSeriesPredictionRuleInterface +} + +// TimeSeriesPredictionRuleInterface has methods to work with TimeSeriesPredictionRule resources. +type TimeSeriesPredictionRuleInterface interface { + Create(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.CreateOptions) (*v1alpha1.TimeSeriesPredictionRule, error) + Update(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (*v1alpha1.TimeSeriesPredictionRule, error) + UpdateStatus(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (*v1alpha1.TimeSeriesPredictionRule, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.TimeSeriesPredictionRule, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.TimeSeriesPredictionRuleList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.TimeSeriesPredictionRule, err error) + TimeSeriesPredictionRuleExpansion +} + +// timeSeriesPredictionRules implements TimeSeriesPredictionRuleInterface +type timeSeriesPredictionRules struct { + client rest.Interface +} + +// newTimeSeriesPredictionRules returns a TimeSeriesPredictionRules +func newTimeSeriesPredictionRules(c *PredictionV1alpha1Client) *timeSeriesPredictionRules { + return &timeSeriesPredictionRules{ + client: c.RESTClient(), + } +} + +// Get takes name of the timeSeriesPredictionRule, and returns the corresponding timeSeriesPredictionRule object, and an error if there is any. +func (c *timeSeriesPredictionRules) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + result = &v1alpha1.TimeSeriesPredictionRule{} + err = c.client.Get(). + Resource("timeseriespredictionrules"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of TimeSeriesPredictionRules that match those selectors. +func (c *timeSeriesPredictionRules) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.TimeSeriesPredictionRuleList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.TimeSeriesPredictionRuleList{} + err = c.client.Get(). + Resource("timeseriespredictionrules"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested timeSeriesPredictionRules. +func (c *timeSeriesPredictionRules) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("timeseriespredictionrules"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a timeSeriesPredictionRule and creates it. Returns the server's representation of the timeSeriesPredictionRule, and an error, if there is any. +func (c *timeSeriesPredictionRules) Create(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.CreateOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + result = &v1alpha1.TimeSeriesPredictionRule{} + err = c.client.Post(). + Resource("timeseriespredictionrules"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(timeSeriesPredictionRule). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a timeSeriesPredictionRule and updates it. Returns the server's representation of the timeSeriesPredictionRule, and an error, if there is any. +func (c *timeSeriesPredictionRules) Update(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + result = &v1alpha1.TimeSeriesPredictionRule{} + err = c.client.Put(). + Resource("timeseriespredictionrules"). + Name(timeSeriesPredictionRule.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(timeSeriesPredictionRule). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *timeSeriesPredictionRules) UpdateStatus(ctx context.Context, timeSeriesPredictionRule *v1alpha1.TimeSeriesPredictionRule, opts v1.UpdateOptions) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + result = &v1alpha1.TimeSeriesPredictionRule{} + err = c.client.Put(). + Resource("timeseriespredictionrules"). + Name(timeSeriesPredictionRule.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(timeSeriesPredictionRule). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the timeSeriesPredictionRule and deletes it. Returns an error if one occurs. +func (c *timeSeriesPredictionRules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("timeseriespredictionrules"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *timeSeriesPredictionRules) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("timeseriespredictionrules"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched timeSeriesPredictionRule. +func (c *timeSeriesPredictionRules) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.TimeSeriesPredictionRule, err error) { + result = &v1alpha1.TimeSeriesPredictionRule{} + err = c.client.Patch(pt). + Resource("timeseriespredictionrules"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index 55c99ac..c51489b 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -76,6 +76,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Prediction().V1alpha1().ClusterNodePredictions().Informer()}, nil case predictionv1alpha1.SchemeGroupVersion.WithResource("timeseriespredictions"): return &genericInformer{resource: resource.GroupResource(), informer: f.Prediction().V1alpha1().TimeSeriesPredictions().Informer()}, nil + case predictionv1alpha1.SchemeGroupVersion.WithResource("timeseriespredictionrules"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Prediction().V1alpha1().TimeSeriesPredictionRules().Informer()}, nil // Group=topology.crane.io, Version=v1alpha1 case topologyv1alpha1.SchemeGroupVersion.WithResource("noderesourcetopologies"): diff --git a/pkg/generated/informers/externalversions/prediction/v1alpha1/interface.go b/pkg/generated/informers/externalversions/prediction/v1alpha1/interface.go index a8d550c..30db8c0 100644 --- a/pkg/generated/informers/externalversions/prediction/v1alpha1/interface.go +++ b/pkg/generated/informers/externalversions/prediction/v1alpha1/interface.go @@ -12,6 +12,8 @@ type Interface interface { ClusterNodePredictions() ClusterNodePredictionInformer // TimeSeriesPredictions returns a TimeSeriesPredictionInformer. TimeSeriesPredictions() TimeSeriesPredictionInformer + // TimeSeriesPredictionRules returns a TimeSeriesPredictionRuleInformer. + TimeSeriesPredictionRules() TimeSeriesPredictionRuleInformer } type version struct { @@ -34,3 +36,8 @@ func (v *version) ClusterNodePredictions() ClusterNodePredictionInformer { func (v *version) TimeSeriesPredictions() TimeSeriesPredictionInformer { return &timeSeriesPredictionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } + +// TimeSeriesPredictionRules returns a TimeSeriesPredictionRuleInformer. +func (v *version) TimeSeriesPredictionRules() TimeSeriesPredictionRuleInformer { + return &timeSeriesPredictionRuleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/informers/externalversions/prediction/v1alpha1/timeseriespredictionrule.go b/pkg/generated/informers/externalversions/prediction/v1alpha1/timeseriespredictionrule.go new file mode 100644 index 0000000..c02d389 --- /dev/null +++ b/pkg/generated/informers/externalversions/prediction/v1alpha1/timeseriespredictionrule.go @@ -0,0 +1,73 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + versioned "github.com/gocrane/api/pkg/generated/clientset/versioned" + internalinterfaces "github.com/gocrane/api/pkg/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/gocrane/api/pkg/generated/listers/prediction/v1alpha1" + predictionv1alpha1 "github.com/gocrane/api/prediction/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// TimeSeriesPredictionRuleInformer provides access to a shared informer and lister for +// TimeSeriesPredictionRules. +type TimeSeriesPredictionRuleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.TimeSeriesPredictionRuleLister +} + +type timeSeriesPredictionRuleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewTimeSeriesPredictionRuleInformer constructs a new informer for TimeSeriesPredictionRule type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewTimeSeriesPredictionRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredTimeSeriesPredictionRuleInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredTimeSeriesPredictionRuleInformer constructs a new informer for TimeSeriesPredictionRule type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredTimeSeriesPredictionRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PredictionV1alpha1().TimeSeriesPredictionRules().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PredictionV1alpha1().TimeSeriesPredictionRules().Watch(context.TODO(), options) + }, + }, + &predictionv1alpha1.TimeSeriesPredictionRule{}, + resyncPeriod, + indexers, + ) +} + +func (f *timeSeriesPredictionRuleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredTimeSeriesPredictionRuleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *timeSeriesPredictionRuleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&predictionv1alpha1.TimeSeriesPredictionRule{}, f.defaultInformer) +} + +func (f *timeSeriesPredictionRuleInformer) Lister() v1alpha1.TimeSeriesPredictionRuleLister { + return v1alpha1.NewTimeSeriesPredictionRuleLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/listers/prediction/v1alpha1/expansion_generated.go b/pkg/generated/listers/prediction/v1alpha1/expansion_generated.go index 3610a42..b411651 100644 --- a/pkg/generated/listers/prediction/v1alpha1/expansion_generated.go +++ b/pkg/generated/listers/prediction/v1alpha1/expansion_generated.go @@ -17,3 +17,7 @@ type TimeSeriesPredictionListerExpansion interface{} // TimeSeriesPredictionNamespaceListerExpansion allows custom methods to be added to // TimeSeriesPredictionNamespaceLister. type TimeSeriesPredictionNamespaceListerExpansion interface{} + +// TimeSeriesPredictionRuleListerExpansion allows custom methods to be added to +// TimeSeriesPredictionRuleLister. +type TimeSeriesPredictionRuleListerExpansion interface{} diff --git a/pkg/generated/listers/prediction/v1alpha1/timeseriespredictionrule.go b/pkg/generated/listers/prediction/v1alpha1/timeseriespredictionrule.go new file mode 100644 index 0000000..684299b --- /dev/null +++ b/pkg/generated/listers/prediction/v1alpha1/timeseriespredictionrule.go @@ -0,0 +1,52 @@ +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/gocrane/api/prediction/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// TimeSeriesPredictionRuleLister helps list TimeSeriesPredictionRules. +// All objects returned here must be treated as read-only. +type TimeSeriesPredictionRuleLister interface { + // List lists all TimeSeriesPredictionRules in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.TimeSeriesPredictionRule, err error) + // Get retrieves the TimeSeriesPredictionRule from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.TimeSeriesPredictionRule, error) + TimeSeriesPredictionRuleListerExpansion +} + +// timeSeriesPredictionRuleLister implements the TimeSeriesPredictionRuleLister interface. +type timeSeriesPredictionRuleLister struct { + indexer cache.Indexer +} + +// NewTimeSeriesPredictionRuleLister returns a new TimeSeriesPredictionRuleLister. +func NewTimeSeriesPredictionRuleLister(indexer cache.Indexer) TimeSeriesPredictionRuleLister { + return &timeSeriesPredictionRuleLister{indexer: indexer} +} + +// List lists all TimeSeriesPredictionRules in the indexer. +func (s *timeSeriesPredictionRuleLister) List(selector labels.Selector) (ret []*v1alpha1.TimeSeriesPredictionRule, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.TimeSeriesPredictionRule)) + }) + return ret, err +} + +// Get retrieves the TimeSeriesPredictionRule from the index for a given name. +func (s *timeSeriesPredictionRuleLister) Get(name string) (*v1alpha1.TimeSeriesPredictionRule, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("timeseriespredictionrule"), name) + } + return obj.(*v1alpha1.TimeSeriesPredictionRule), nil +} diff --git a/prediction/v1alpha1/register.go b/prediction/v1alpha1/register.go index 4e1de92..9f41753 100644 --- a/prediction/v1alpha1/register.go +++ b/prediction/v1alpha1/register.go @@ -44,6 +44,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &TimeSeriesPredictionList{}, &ClusterNodePrediction{}, &ClusterNodePredictionList{}, + &TimeSeriesPredictionRule{}, + &TimeSeriesPredictionRuleList{}, ) // AddToGroupVersion allows the serialization of client types like ListOptions. v1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/prediction/v1alpha1/types.go b/prediction/v1alpha1/types.go index 5dca576..a61501f 100644 --- a/prediction/v1alpha1/types.go +++ b/prediction/v1alpha1/types.go @@ -8,8 +8,9 @@ import ( type AlgorithmType string const ( - AlgorithmTypePercentile AlgorithmType = "percentile" - AlgorithmTypeDSP AlgorithmType = "dsp" + AlgorithmTypePercentile AlgorithmType = "percentile" + AlgorithmTypeDSP AlgorithmType = "dsp" + AlgorithmTypeSegmentedPercentile AlgorithmType = "sp" ) // PredictionMode represents the prediction time series mode. @@ -103,6 +104,17 @@ type Percentile struct { TargetUtilization string `json:"targetUtilization,omitempty"` } +type SP struct { + Aggregated bool `json:"aggregated,omitempty"` + HistoryLength string `json:"historyLength,omitempty"` + SampleInterval string `json:"sampleInterval,omitempty"` + Histogram HistogramConfig `json:"histogram,omitempty"` + MinSampleWeight string `json:"minSampleWeight,omitempty"` + MarginFraction string `json:"marginFraction,omitempty"` + Percentile string `json:"percentile,omitempty"` + TargetUtilization string `json:"targetUtilization,omitempty"` +} + type HistogramConfig struct { MaxValue string `json:"maxValue,omitempty"` Epsilon string `json:"epsilon,omitempty"` @@ -245,6 +257,9 @@ type Algorithm struct { // +optional // Percentile is an algorithm which use exponential time decay histogram, it can predict a reasonable value according your history time series Percentile *Percentile `json:"percentile,omitempty"` + // +optional + // SP is an algorithm which use exponential time decay histogram, it can predict a 24 reasonable value according your history time series + SP *SP `json:"sp,omitempty"` } type MetricTimeSeriesList []*MetricTimeSeries @@ -292,3 +307,121 @@ type TimeSeriesPredictionList struct { Items []TimeSeriesPrediction `json:"items"` } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Cluster,shortName=tspr +// +kubebuilder:printcolumn:name="RunInterval",type=string,JSONPath=`.spec.runInterval` +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp",description="CreationTimestamp is a timestamp representing the server time when this object was created." +// +kubebuilder:subresource:status + +// TimeSeriesPredictionRule represents the configuration of an TimeSeriesPredictionRule object. +type TimeSeriesPredictionRule struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +optional + Spec TimeSeriesPredictionRuleSpec `json:"spec"` + + // +optional + Status TimeSeriesPredictionRuleStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TimeSeriesPredictionRuleList is a list of TimeSeriesPredictionRule items. +type TimeSeriesPredictionRuleList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []TimeSeriesPredictionRule `json:"items"` +} + +// TimeSeriesPredictionRuleSpec defines resources and runInterval to recommend +type TimeSeriesPredictionRuleSpec struct { + // ResourceSelector indicates how to select resources(e.g. a set of Deployments) for a Recommendation. + // +required + // +kubebuilder:validation:Required + ResourceSelectors []ResourceSelector `json:"resourceSelectors"` + + // NamespaceSelector indicates resource namespaces to select from + NamespaceSelector NamespaceSelector `json:"namespaceSelector"` + + // RunInterval between two recommendation + RunInterval string `json:"runInterval,omitempty"` + + // List of recommender type to run + Recommenders []Recommender `json:"recommenders"` +} + +// ResourceSelector describes how the resources will be selected. +type ResourceSelector struct { + // Kind of the resource, e.g. Deployment + Kind string `json:"kind"` + + // API version of the resource, e.g. "apps/v1" + // +optional + APIVersion string `json:"apiVersion"` + + // Name of the resource. + // +optional + Name string `json:"name,omitempty"` + + // +optional + LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` +} + +// NamespaceSelector describes how to select namespaces for recommend +type NamespaceSelector struct { + // Select all namespace if true + Any bool `json:"any,omitempty"` + // List of namespace names to select from. + MatchNames []string `json:"matchNames,omitempty"` +} + +// Recommender referring to the Recommender in RecommendationConfiguration +type Recommender struct { + + // Recommender's Name + Name string `json:"name"` + // Override Recommendation configs + // +optional + Config map[string]string `json:"config,omitempty"` +} + +// TimeSeriesPredictionRuleStatus represents the current state of an TimeSeriesPredictionRule item. +type TimeSeriesPredictionRuleStatus struct { + // LastUpdateTime is the last time the status updated. + // +optional + LastUpdateTime *metav1.Time `json:"lastUpdateTime,omitempty"` + + // Recommendations is a list of RecommendationMission that run parallel. + // +optional + // +listType=atomic + Recommendations []RecommendationMission `json:"recommendations,omitempty"` + + // RunNumber is the numbers of runs + // +optional + RunNumber int32 `json:"runNumber,omitempty"` +} + +type RecommendationMission struct { + v1.ObjectReference `json:",inline"` + + // +optional + TargetRef v1.ObjectReference `json:"targetRef"` + + // LastStartTime is last time we start a recommendation mission. + // +optional + LastStartTime *metav1.Time `json:"lastStartTime,omitempty"` + + // Message presents the running message for this mission + // +optional + Message string `json:"message,omitempty"` + + // RecommenderRef presents recommender info for recommendation mission. + // +optional + RecommenderRef Recommender `json:"recommenderRef"` +} diff --git a/prediction/v1alpha1/zz_generated.deepcopy.go b/prediction/v1alpha1/zz_generated.deepcopy.go index 7739fb5..f1f58e0 100644 --- a/prediction/v1alpha1/zz_generated.deepcopy.go +++ b/prediction/v1alpha1/zz_generated.deepcopy.go @@ -24,6 +24,11 @@ func (in *Algorithm) DeepCopyInto(out *Algorithm) { *out = new(Percentile) **out = **in } + if in.SP != nil { + in, out := &in.SP, &out.SP + *out = new(SP) + **out = **in + } return } @@ -369,6 +374,27 @@ func (in MetricTimeSeriesList) DeepCopy() MetricTimeSeriesList { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespaceSelector) DeepCopyInto(out *NamespaceSelector) { + *out = *in + if in.MatchNames != nil { + in, out := &in.MatchNames, &out.MatchNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceSelector. +func (in *NamespaceSelector) DeepCopy() *NamespaceSelector { + if in == nil { + return nil + } + out := new(NamespaceSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Percentile) DeepCopyInto(out *Percentile) { *out = *in @@ -484,6 +510,90 @@ func (in *QueryCondition) DeepCopy() *QueryCondition { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RecommendationMission) DeepCopyInto(out *RecommendationMission) { + *out = *in + out.ObjectReference = in.ObjectReference + out.TargetRef = in.TargetRef + if in.LastStartTime != nil { + in, out := &in.LastStartTime, &out.LastStartTime + *out = (*in).DeepCopy() + } + in.RecommenderRef.DeepCopyInto(&out.RecommenderRef) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecommendationMission. +func (in *RecommendationMission) DeepCopy() *RecommendationMission { + if in == nil { + return nil + } + out := new(RecommendationMission) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Recommender) DeepCopyInto(out *Recommender) { + *out = *in + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Recommender. +func (in *Recommender) DeepCopy() *Recommender { + if in == nil { + return nil + } + out := new(Recommender) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSelector) DeepCopyInto(out *ResourceSelector) { + *out = *in + if in.LabelSelector != nil { + in, out := &in.LabelSelector, &out.LabelSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSelector. +func (in *ResourceSelector) DeepCopy() *ResourceSelector { + if in == nil { + return nil + } + out := new(ResourceSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SP) DeepCopyInto(out *SP) { + *out = *in + out.Histogram = in.Histogram + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SP. +func (in *SP) DeepCopy() *SP { + if in == nil { + return nil + } + out := new(SP) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Sample) DeepCopyInto(out *Sample) { *out = *in @@ -561,6 +671,125 @@ func (in *TimeSeriesPredictionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TimeSeriesPredictionRule) DeepCopyInto(out *TimeSeriesPredictionRule) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeSeriesPredictionRule. +func (in *TimeSeriesPredictionRule) DeepCopy() *TimeSeriesPredictionRule { + if in == nil { + return nil + } + out := new(TimeSeriesPredictionRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TimeSeriesPredictionRule) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TimeSeriesPredictionRuleList) DeepCopyInto(out *TimeSeriesPredictionRuleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TimeSeriesPredictionRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeSeriesPredictionRuleList. +func (in *TimeSeriesPredictionRuleList) DeepCopy() *TimeSeriesPredictionRuleList { + if in == nil { + return nil + } + out := new(TimeSeriesPredictionRuleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TimeSeriesPredictionRuleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TimeSeriesPredictionRuleSpec) DeepCopyInto(out *TimeSeriesPredictionRuleSpec) { + *out = *in + if in.ResourceSelectors != nil { + in, out := &in.ResourceSelectors, &out.ResourceSelectors + *out = make([]ResourceSelector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.NamespaceSelector.DeepCopyInto(&out.NamespaceSelector) + if in.Recommenders != nil { + in, out := &in.Recommenders, &out.Recommenders + *out = make([]Recommender, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeSeriesPredictionRuleSpec. +func (in *TimeSeriesPredictionRuleSpec) DeepCopy() *TimeSeriesPredictionRuleSpec { + if in == nil { + return nil + } + out := new(TimeSeriesPredictionRuleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TimeSeriesPredictionRuleStatus) DeepCopyInto(out *TimeSeriesPredictionRuleStatus) { + *out = *in + if in.LastUpdateTime != nil { + in, out := &in.LastUpdateTime, &out.LastUpdateTime + *out = (*in).DeepCopy() + } + if in.Recommendations != nil { + in, out := &in.Recommendations, &out.Recommendations + *out = make([]RecommendationMission, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeSeriesPredictionRuleStatus. +func (in *TimeSeriesPredictionRuleStatus) DeepCopy() *TimeSeriesPredictionRuleStatus { + if in == nil { + return nil + } + out := new(TimeSeriesPredictionRuleStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TimeSeriesPredictionSpec) DeepCopyInto(out *TimeSeriesPredictionSpec) { *out = *in