Skip to content

Commit

Permalink
RHIROS-1326 Kruize 0.0.20_rm Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
saltgen committed Sep 28, 2023
1 parent 6f54036 commit 01b75a8
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 169 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ upload-msg-to-rosocp:
get-recommendations:
ifdef env
$(eval APIPOD=$(shell oc get pods -o custom-columns=POD:.metadata.name --no-headers -n ${env} | grep ros-ocp-backend-api))
oc exec ${APIPOD} -c ros-ocp-backend-api -n ${env} -- /bin/bash -c 'curl -s -H "X-Rh-Identity: ${b64_identity}" -H "x-rh-request_id: testtesttest" http://localhost:8000/api/cost-management/v1/recommendations/openshift' | python -m json.tool
oc exec ${APIPOD} -c ros-ocp-backend-api -n ${env} -- /bin/bash -c 'curl -s -H "X-Rh-Identity: ${b64_identity}" -H "x-rh-request_id: testtesttest" http://localhost:8000/api/cost-management/v1/recommendations/openshift?start_date=1992-12-26' | python -m json.tool
else
curl -s -H "x-rh-identity: ${b64_identity}" \
-H "x-rh-request_id: testtesttest" \
http://localhost:8000/api/cost-management/v1/recommendations/openshift | python -m json.tool
http://localhost:8000/api/cost-management/v1/recommendations/openshift?start_date=1992-12-26 | python -m json.tool
endif
10 changes: 5 additions & 5 deletions internal/api/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,6 @@ func TransformComponentUnits(jsonData datatypes.JSON) map[string]interface{} {
return nil
}

durationBased, ok := data["duration_based"].(map[string]interface{})
if !ok {
fmt.Printf("duration_based not found in JSON")
}

convertMemory := func(memory map[string]interface{}) error {
amount, ok := memory["amount"].(float64)
if ok {
Expand Down Expand Up @@ -274,6 +269,11 @@ func TransformComponentUnits(jsonData datatypes.JSON) map[string]interface{} {
return nil
}

durationBased, ok := data["duration_based"].(map[string]interface{})
if !ok {
fmt.Printf("duration_based not found in JSON")
}

/*
Recommendation data is available for three periods
For each of these actual values will be present in
Expand Down
10 changes: 5 additions & 5 deletions internal/services/report_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func ProcessReport(msg *kafka.Message) {
continue
}

if kruize.Is_valid_recommendation(recommendation) {
if kruize.Is_valid_recommendation(recommendation, experiment_name, maxEndTime.String()) {
containers := recommendation[0].Kubernetes_objects[0].Containers
for _, container := range containers {
for _, v := range container.Recommendations.Data {
Expand All @@ -212,8 +212,8 @@ func ProcessReport(msg *kafka.Message) {
recommendationSet := model.RecommendationSet{
WorkloadID: workload.ID,
ContainerName: container.Container_name,
MonitoringStartTime: v.Duration_based.Short_term.Monitoring_start_time,
MonitoringEndTime: v.Duration_based.Short_term.Monitoring_end_time,
MonitoringStartTime: v.RecommendationTerms.Short_term.MonitoringStartTime,
MonitoringEndTime: v.MonitoringEndTime,
Recommendations: marshalData,
}
if err := recommendationSet.CreateRecommendationSet(); err != nil {
Expand All @@ -227,8 +227,8 @@ func ProcessReport(msg *kafka.Message) {
historicalRecommendationSet := model.HistoricalRecommendationSet{
WorkloadID: workload.ID,
ContainerName: container.Container_name,
MonitoringStartTime: v.Duration_based.Short_term.Monitoring_start_time,
MonitoringEndTime: v.Duration_based.Short_term.Monitoring_end_time,
MonitoringStartTime: v.RecommendationTerms.Short_term.MonitoringStartTime,
MonitoringEndTime: v.MonitoringEndTime,
Recommendations: marshalData,
}
if err := historicalRecommendationSet.CreateHistoricalRecommendationSet(); err != nil {
Expand Down
45 changes: 28 additions & 17 deletions internal/types/kruizePayload/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,36 +38,47 @@ type aggregation_info struct {
}

type recommendation struct {
Data map[string]recommendationType `json:"data,omitempty"`
Version string `json:"version,omitempty"`
Data map[string]RecommendationData `json:"data,omitempty"`
Notifications map[string]notification `json:"notifications,omitempty"`
}


type notification struct {
NotifyType string `json:"type,omitempty"`
Message string `json:"message,omitempty"`
Code int `json:"code,omitempty"`
}

type recommendationType struct {
Duration_based termbased `json:"duration_based,omitempty"`
type RecommendationEngineObject struct {
PodsCount int `json:"pods_count,omitempty"`
ConfidenceLevel float64 `json:"confidence_level,omitempty"`
Config ConfigObject `json:"config,omitempty"`
Variation ConfigObject `json:"variation,omitempty"`
Notifications map[string]notification `json:"notifications,omitempty"`
}

type RecommendationData struct {
Notifications map[string]notification `json:"notifications"`
MonitoringEndTime time.Time `json:"monitoring_end_time"`
Current ConfigObject `json:"current"`
RecommendationTerms TermBased `json:"recommendation_terms"`
}

type termbased struct {
Short_term recommendationObject `json:"short_term,omitempty"`
Medium_term recommendationObject `json:"medium_term,omitempty"`
Long_term recommendationObject `json:"long_term,omitempty"`
type RecommendationTerm struct {
DurationInHours float64 `json:"duration_in_hours"`
Notifications map[string]notification `json:"notifications"`
MonitoringStartTime time.Time
RecommendationEngines struct {
Cost RecommendationEngineObject `json:"cost"`
Performance RecommendationEngineObject `json:"performance"`
} `json:"recommendation_engines"`
}

type recommendationObject struct {
Monitoring_start_time time.Time `json:"monitoring_start_time,omitempty"`
Monitoring_end_time time.Time `json:"monitoring_end_time,omitempty"`
Duration_in_hours float64 `json:"duration_in_hours,omitempty"`
Pods_count int `json:"pods_count,omitempty"`
Confidence_level float64 `json:"confidence_level,omitempty"`
Current ConfigObject `json:"current,omitempty"`
Config ConfigObject `json:"config,omitempty"`
Variation ConfigObject `json:"variation,omitempty"`
Notifications map[string]notification `json:"notifications,omitempty"`
type TermBased struct {
Short_term RecommendationTerm `json:"short_term,omitempty"`
Medium_term RecommendationTerm `json:"medium_term,omitempty"`
Long_term RecommendationTerm `json:"long_term,omitempty"`
}

type ConfigObject struct {
Expand Down
48 changes: 42 additions & 6 deletions internal/utils/kruize/kruize_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,50 @@ func Update_recommendations(experiment_name string, interval_end_time time.Time)

}

func Is_valid_recommendation(d []kruizePayload.ListRecommendations) bool {
func Is_valid_recommendation(d []kruizePayload.ListRecommendations, experiment_name string, maxEndTime string) bool {
if len(d) > 0 {

// To maintain a local reference the following map has been created from
// https://github.com/kruize/autotune/blob/master/design/NotificationCodes.md#detailed-codes
notificationCodeValidities := map[string]string{
"111000": "INFO",
"120001": "INFO",
"221001": "ERROR",
"221002": "ERROR",
"221003": "ERROR",
"221004": "ERROR",
"223001": "ERROR",
"223002": "ERROR",
"223003": "ERROR",
"223004": "ERROR",
"224001": "ERROR",
"224002": "ERROR",
"224003": "ERROR",
"224004": "ERROR",
}

notifications := d[0].Kubernetes_objects[0].Containers[0].Recommendations.Notifications
// 112101 is notification code for "Duration Based Recommendations Available".
if _, ok := notifications["112101"]; ok {
return true
} else {
return false

for key := range notifications{
notificationType, keyExists := notificationCodeValidities[key]
if !keyExists {
return false
}

if key == "111000" && notificationType == "INFO"{
notificationsLevelTwo := d[0].Kubernetes_objects[0].Containers[0].Recommendations.Data[maxEndTime].Notifications
for key := range notificationsLevelTwo{
if notificationCodeValidities[key] == "ERROR"{
kruizeInvalidRecommendationDetail.WithLabelValues(key, experiment_name).Set(1)
}
}
return true
} else {
// Setting the metric counter to 1 as we expect a single metric
// for a combination of notification_code and experiment_name
kruizeInvalidRecommendationDetail.WithLabelValues(key, experiment_name).Set(1)
return false
}
}
}
return false
Expand Down
11 changes: 11 additions & 0 deletions internal/utils/kruize/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ var (
[]string{"path"},
)
)


var (
kruizeInvalidRecommendationDetail = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "rosocp_kruize_invalid_recommendation_detail",
Help: "List of INFO/ERROR type recommendations from Kruize",
},
[]string{"notification_code", "experiment_name"},
)
)
Loading

0 comments on commit 01b75a8

Please sign in to comment.