diff --git a/cmd/cli/app/profile/status/status_list.go b/cmd/cli/app/profile/status/status_list.go index 1b793c0437..75c6372ccd 100644 --- a/cmd/cli/app/profile/status/status_list.go +++ b/cmd/cli/app/profile/status/status_list.go @@ -46,7 +46,8 @@ func listCommand(ctx context.Context, cmd *cobra.Command, conn *grpc.ClientConn) profileName := viper.GetString("name") format := viper.GetString("output") all := viper.GetBool("detailed") - rule := viper.GetString("rule") + ruleType := viper.GetString("ruleType") + ruleName := viper.GetString("ruleName") // Ensure provider is supported if !app.IsProviderSupported(provider) { @@ -59,10 +60,11 @@ func listCommand(ctx context.Context, cmd *cobra.Command, conn *grpc.ClientConn) } resp, err := client.GetProfileStatusByName(ctx, &minderv1.GetProfileStatusByNameRequest{ - Context: &minderv1.Context{Provider: &provider, Project: &project}, - Name: profileName, - All: all, - Rule: rule, + Context: &minderv1.Context{Provider: &provider, Project: &project}, + Name: profileName, + All: all, + RuleType: ruleType, + RuleName: ruleName, }) if err != nil { return cli.MessageAndError("Error getting profile status", err) @@ -98,5 +100,6 @@ func init() { profileStatusCmd.AddCommand(listCmd) // Flags listCmd.Flags().BoolP("detailed", "d", false, "List all profile violations") - listCmd.Flags().StringP("rule", "r", "", "Filter profile status list by rule") + listCmd.Flags().StringP("ruleType", "r", "", "Filter profile status list by rule type") + listCmd.Flags().String("ruleName", "", "Filter profile status list by rule name") } diff --git a/cmd/cli/app/profile/table_render.go b/cmd/cli/app/profile/table_render.go index c929cb76fb..c4ae04ca09 100644 --- a/cmd/cli/app/profile/table_render.go +++ b/cmd/cli/app/profile/table_render.go @@ -158,7 +158,7 @@ func RenderRuleEvaluationStatusTable( for _, eval := range statuses { t.AddRowWithColor( layouts.NoColor(eval.RuleId), - layouts.NoColor(eval.RuleName), + layouts.NoColor(eval.RuleDescriptionName), layouts.NoColor(eval.Entity), getColoredEvalStatus(eval.Status), getRemediateStatusColor(eval.RemediationStatus), diff --git a/database/migrations/000013_rule_evaluations_rule_name.down.sql b/database/migrations/000013_rule_evaluations_rule_name.down.sql new file mode 100644 index 0000000000..52496994b0 --- /dev/null +++ b/database/migrations/000013_rule_evaluations_rule_name.down.sql @@ -0,0 +1,79 @@ +-- Copyright 2024 Stacklok, Inc +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- Begin transaction +BEGIN; + +-- Prevent concurrent updates to rule_evaluations +SELECT * +FROM rule_evaluations FOR UPDATE; + +-- Delete duplicate rule evaluation results without considering rule_name +-- Using CTID as postgres doesn't have min, max aggregators for uuid (too much code to add one) +DELETE +FROM rule_evaluations +WHERE CTID IN (SELECT MIN(CTID) AS CTID + FROM rule_evaluations + GROUP BY entity, profile_id, repository_id, rule_type_id, + COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), + COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID) + HAVING COUNT(*) > 1); + + +-- Drop the existing unique index on rule_evaluations +DROP INDEX IF EXISTS rule_evaluations_results_idx; + +-- Recreate the unique index without rule_name +CREATE UNIQUE INDEX rule_evaluations_results_idx + ON rule_evaluations (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), + entity, rule_type_id, COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID)); + +-- Remove the rule_name column from rule_evaluations +ALTER TABLE rule_evaluations + DROP COLUMN IF EXISTS rule_name; + +-- Function to remove the "name" field from a JSONB array +CREATE OR REPLACE FUNCTION remove_name_from_jsonb_array(input_jsonb jsonb) RETURNS jsonb AS +$$ +DECLARE + updated_array jsonb; + element jsonb; +BEGIN + updated_array := '[]'::jsonb; + + FOR element IN SELECT * FROM jsonb_array_elements(input_jsonb) + LOOP + element := element - 'name'; + updated_array := updated_array || jsonb_build_array(element); + END LOOP; + + RETURN updated_array; +END; +$$ LANGUAGE plpgsql; + +-- Prevent concurrent updates to entity_profiles +SELECT * +FROM entity_profiles FOR UPDATE; + +-- Update the entity_profiles table to remove the "name" key from the "contextual_rules" JSONB array +UPDATE entity_profiles +SET contextual_rules = remove_name_from_jsonb_array(contextual_rules), + updated_at = now() +WHERE true; + +-- Drop the created function +DROP FUNCTION IF EXISTS remove_name_from_jsonb_array(input_jsonb jsonb); + +-- Commit transaction +COMMIT; diff --git a/database/migrations/000013_rule_evaluations_rule_name.up.sql b/database/migrations/000013_rule_evaluations_rule_name.up.sql new file mode 100644 index 0000000000..8717542897 --- /dev/null +++ b/database/migrations/000013_rule_evaluations_rule_name.up.sql @@ -0,0 +1,111 @@ +-- Copyright 2024 Stacklok, Inc +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- Begin transaction +BEGIN; + +-- Add rule_name to rule_evaluations +ALTER TABLE rule_evaluations + ADD COLUMN rule_name TEXT; + +-- Drop the existing unique index on rule_evaluations +DROP INDEX IF EXISTS rule_evaluations_results_idx; + +-- Recreate the unique index with rule_name +CREATE UNIQUE INDEX rule_evaluations_results_idx + ON rule_evaluations (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), + entity, rule_type_id, COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), + rule_name); + +-- Function to add a descriptive name to each element in a JSONB array +CREATE OR REPLACE FUNCTION add_descriptive_name_to_jsonb_array(input_jsonb jsonb) RETURNS jsonb AS +$$ +DECLARE + updated_array jsonb; + element jsonb; + element_type text; +BEGIN + updated_array := '[]'::jsonb; + + FOR element IN SELECT * FROM jsonb_array_elements(input_jsonb) + LOOP + element_type := element ->> 'type'; + + IF (SELECT COUNT(*) FROM jsonb_array_elements(input_jsonb) WHERE value ->> 'type' = element_type) > 1 THEN + element := jsonb_set(element, '{name}', ('"' || element_type || '_' || gen_random_uuid() || '"')::jsonb); + ELSE + element := jsonb_set(element, '{name}', ('"' || element_type || '"')::jsonb); + END IF; + + updated_array := updated_array || jsonb_build_array(element); + END LOOP; + + RETURN updated_array; +END; +$$ LANGUAGE plpgsql; + +-- Function to get the rule name for a given entity, profile and rule id. +CREATE OR REPLACE FUNCTION get_rule_name(entity entities, profile_id uuid, rule_type_id uuid) RETURNS text AS +$$ +DECLARE + rule_name text; + rule_type_name text; + rules jsonb; +BEGIN + SELECT entity_profiles.contextual_rules + INTO rules + FROM entity_profiles + WHERE entity_profiles.profile_id = get_rule_name.profile_id + AND entity_profiles.entity = get_rule_name.entity; + + SELECT rule_type.name INTO rule_type_name FROM rule_type WHERE id = get_rule_name.rule_type_id; + + SELECT rule_element ->> 'name' + INTO rule_name + FROM jsonb_array_elements(rules) rule_element + WHERE rule_element ->> 'type' = rule_type_name; + + RETURN rule_name; +END; +$$ LANGUAGE plpgsql STABLE; + +-- Prevent entity_profiles to be updated outside the transaction +SELECT * +FROM entity_profiles FOR UPDATE; + +-- Update existing rules to have the name field, internally this field is mandatory +UPDATE entity_profiles +SET contextual_rules = add_descriptive_name_to_jsonb_array(entity_profiles.contextual_rules), + updated_at = now() +WHERE true; + +-- Prevent rule_evaluations to be updated outside the transaction +SELECT * +FROM rule_evaluations FOR UPDATE; + +-- Update rule evaluations +UPDATE rule_evaluations +SET rule_name = get_rule_name(rule_evaluations.entity, rule_evaluations.profile_id, rule_evaluations.rule_type_id) +WHERE true; + +-- Add non null constraint on rule_name +ALTER TABLE rule_evaluations + ALTER COLUMN rule_name SET NOT NULL; + +-- Drop the created functions +DROP FUNCTION IF EXISTS add_descriptive_name_to_jsonb_array(input_jsonb jsonb); +DROP FUNCTION IF EXISTS get_rule_name(entity entities, profile_id uuid, rule_type_id uuid); + +-- transaction commit +COMMIT; diff --git a/database/mock/store.go b/database/mock/store.go index 55ee80ca6c..4f7c4f6b39 100644 --- a/database/mock/store.go +++ b/database/mock/store.go @@ -1277,18 +1277,18 @@ func (mr *MockStoreMockRecorder) GetRootProjects(arg0 interface{}) *gomock.Call } // GetRuleEvaluationByProfileIdAndRuleType mocks base method. -func (m *MockStore) GetRuleEvaluationByProfileIdAndRuleType(arg0 context.Context, arg1 uuid.UUID, arg2 db.NullEntities, arg3 uuid.NullUUID, arg4 sql.NullString) (db.ListRuleEvaluationsByProfileIdRow, error) { +func (m *MockStore) GetRuleEvaluationByProfileIdAndRuleType(arg0 context.Context, arg1 uuid.UUID, arg2 db.NullEntities, arg3 sql.NullString, arg4 uuid.NullUUID, arg5 sql.NullString) (db.ListRuleEvaluationsByProfileIdRow, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRuleEvaluationByProfileIdAndRuleType", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "GetRuleEvaluationByProfileIdAndRuleType", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(db.ListRuleEvaluationsByProfileIdRow) ret1, _ := ret[1].(error) return ret0, ret1 } // GetRuleEvaluationByProfileIdAndRuleType indicates an expected call of GetRuleEvaluationByProfileIdAndRuleType. -func (mr *MockStoreMockRecorder) GetRuleEvaluationByProfileIdAndRuleType(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetRuleEvaluationByProfileIdAndRuleType(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRuleEvaluationByProfileIdAndRuleType", reflect.TypeOf((*MockStore)(nil).GetRuleEvaluationByProfileIdAndRuleType), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRuleEvaluationByProfileIdAndRuleType", reflect.TypeOf((*MockStore)(nil).GetRuleEvaluationByProfileIdAndRuleType), arg0, arg1, arg2, arg3, arg4, arg5) } // GetRuleTypeByID mocks base method. diff --git a/database/query/profile_status.sql b/database/query/profile_status.sql index 78461cfc85..0bb86dc1e4 100644 --- a/database/query/profile_status.sql +++ b/database/query/profile_status.sql @@ -1,9 +1,9 @@ -- name: UpsertRuleEvaluations :one INSERT INTO rule_evaluations ( - profile_id, repository_id, artifact_id, pull_request_id, rule_type_id, entity -) VALUES ($1, $2, $3, $4, $5, $6) -ON CONFLICT (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), entity, rule_type_id) + profile_id, repository_id, artifact_id, pull_request_id, rule_type_id, entity, rule_name +) VALUES ($1, $2, $3, $4, $5, $6, $7) +ON CONFLICT (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), entity, rule_type_id, rule_name) DO UPDATE SET profile_id = $1 RETURNING id; @@ -79,7 +79,7 @@ WHERE p.project_id = $1; DELETE FROM rule_evaluations WHERE id IN ( SELECT id FROM rule_evaluations as re - WHERE re.profile_id = $1 AND re.rule_type_id = $2 FOR UPDATE); + WHERE re.profile_id = $1 AND re.rule_type_id = $2 AND re.rule_name = $3 FOR UPDATE); -- name: ListRuleEvaluationsByProfileId :many WITH @@ -122,6 +122,7 @@ SELECT ad.alert_last_updated, res.repository_id, res.entity, + res.rule_name, repo.repo_name, repo.repo_owner, repo.provider, @@ -143,5 +144,6 @@ WHERE res.profile_id = $1 AND WHEN sqlc.narg(entity_id)::UUID IS NULL THEN true ELSE false END - ) AND (rt.name = sqlc.narg(rule_name) OR sqlc.narg(rule_name) IS NULL) + ) AND (rt.name = sqlc.narg(rule_type_name) OR sqlc.narg(rule_type_name) IS NULL) + AND (res.rule_name = sqlc.narg(rule_name) OR sqlc.narg(rule_name) IS NULL) ; diff --git a/docs/docs/how-to/create_profile.md b/docs/docs/how-to/create_profile.md index daef8da5d2..392bc22215 100644 --- a/docs/docs/how-to/create_profile.md +++ b/docs/docs/how-to/create_profile.md @@ -230,6 +230,8 @@ alert: "on" remediate: "on" repository: - type: secret_scanning + name: "secret_scanning_github" # Optional, as there aren't multiple rules + # of the same type under the entity - repository def: enabled: true ``` @@ -250,4 +252,86 @@ filter the output using `jq`. For example, to get all rules that pertain to the run the following command: ```bash minder profile status list --name stacklok-remediate-profile -d -ojson 2>/dev/null | jq -C '.ruleEvaluationStatus | map(select(.entityInfo.repo_name == "minder" and .status == "failure"))' -``` \ No newline at end of file +``` + +## Defining Rule Names in Profiles + +In Minder profiles, rules are identified by their type and, optionally, a unique name. + +### Rule Types vs Rule Names + +Rule types are mandatory and refer to the kind of rule being applied. Rule names, on the other hand, are optional +identifiers that become crucial when multiple rules of the same type exist under an entity. + +```yaml +repository: + - type: secret_scanning + name: "secret_scanning_github" + def: + enabled: true +``` +In this example, `secret_scanning` is the rule type and `secret_scanning_github` is the rule name. + +### When are Rule Names Mandatory? + +If you're using multiple rules of the same type under an entity, each rule must have a unique name. This helps +distinguish between rules and understand their specific purpose. + +```yaml +repository: + - type: secret_scanning + name: "secret_scanning_github" + def: + enabled: true + - type: secret_scanning + name: "secret_scanning_github_2" + def: + enabled: false +``` +Here, we have two rules of the same type `secret_scanning` under the `repository` entity. Each rule has a unique name. + +### Uniqueness of Rule Names + +No two rules, whether of the same type or different types, can have the same name under an entity. This avoids +confusion and ensures each rule can be individually managed. + +```yaml +repository: # Would return an error while creating + - type: secret_scanning + name: "protect_github" + def: + enabled: true + - type: secret_push_protection + name: "protect_github" + def: + enabled: false +``` +In this example, even though the rules are of different types (`secret_scanning` and `secret_push_protection`), +Minder will return an error while creating this profile as rule names are same under the same entity. +You may use same rule names under different entities (repository, artifacts, etc.) + +Also, a rule's `type` and `name` should not be identical. + +### Example + +Consider a profile with two `dependabot_configured` rules under the `repository` entity. The first rule has a unique +name, "Dependabot Configured for GoLang". The second rule doesn't have a name, which is acceptable as Minder would +internally use the rule type as the name for the rule. + +```yaml +repository: + - type: dependabot_configured + name: "Dependabot Configured for GoLang" + def: + package_ecosystem: gomod + schedule_interval: daily + apply_if_file: go.mod + - type: dependabot_configured # internally 'name' would be 'dependabot_configured' + def: + package_ecosystem: npm + schedule_interval: daily + apply_if_file: docs/package.json +``` + +You can find the rule definitions used above and many profile examples at +[minder-rules-and-profiles](https://github.com/stacklok/minder-rules-and-profiles) repository. diff --git a/docs/docs/ref/proto.md b/docs/docs/ref/proto.md index 75ae9628e4..684d25df4a 100644 --- a/docs/docs/ref/proto.md +++ b/docs/docs/ref/proto.md @@ -526,7 +526,8 @@ get profile by id | name | [string](#string) | | name is the name of the profile to get | | entity | [GetProfileStatusByNameRequest.EntityTypedId](#minder-v1-GetProfileStatusByNameRequest-EntityTypedId) | | | | all | [bool](#bool) | | | -| rule | [string](#string) | | | +| rule_type | [string](#string) | | | +| rule_name | [string](#string) | | | @@ -917,6 +918,7 @@ Rule defines the individual call of a certain rule type. | type | [string](#string) | | type is the type of the rule to be instantiated. | | params | [google.protobuf.Struct](#google-protobuf-Struct) | | params are the parameters that are passed to the rule. This is optional and depends on the rule type. | | def | [google.protobuf.Struct](#google-protobuf-Struct) | | def is the definition of the rule. This depends on the rule type. | +| name | [string](#string) | | name is the descriptive name of the rule, not to be confused with type | @@ -1106,7 +1108,6 @@ get the status of the rules for a given profile | ----- | ---- | ----- | ----------- | | profile_id | [string](#string) | | profile_id is the id of the profile | | rule_id | [string](#string) | | rule_id is the id of the rule | -| rule_name | [string](#string) | | rule_name is the name of the rule | | entity | [string](#string) | | entity is the entity that was evaluated | | status | [string](#string) | | status is the status of the evaluation | | last_updated | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | last_updated is the last time the profile was updated | @@ -1116,6 +1117,8 @@ get the status of the rules for a given profile | remediation_status | [string](#string) | | remediation_status is the status of the remediation | | remediation_last_updated | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | remediation_last_updated is the last time the remediation was performed or attempted | | remediation_details | [string](#string) | | remediation_details is the description of the remediation attempt if any | +| rule_type_name | [string](#string) | | rule_type_name is the name of the rule | +| rule_description_name | [string](#string) | | rule_description_name is the name to describe the rule | diff --git a/internal/controlplane/handlers_profile.go b/internal/controlplane/handlers_profile.go index d61b06fc59..3bd47a32c1 100644 --- a/internal/controlplane/handlers_profile.go +++ b/internal/controlplane/handlers_profile.go @@ -27,6 +27,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + "k8s.io/apimachinery/pkg/util/sets" "github.com/stacklok/minder/internal/db" "github.com/stacklok/minder/internal/engine" @@ -44,6 +45,11 @@ type entityAndRuleTuple struct { RuleID uuid.UUID } +type ruleTypeAndNamePair struct { + RuleType string + RuleName string +} + // validateActionType returns the appropriate remediate type or the // NULL DB type if the input is invalid, thus letting the server run // the profile with the default remediate type. @@ -101,6 +107,9 @@ func (s *Server) CreateProfile(ctx context.Context, return nil, status.Errorf(codes.Internal, "error creating profile") } + // Adds default rule names, if not present + populateRuleNames(in) + // Now that we know it's valid, let's persist it! tx, err := s.store.BeginTransaction() if err != nil { @@ -183,7 +192,7 @@ func createProfileRulesForEntity( profile *db.Profile, qtx db.Querier, rules []*minderv1.Profile_Rule, - rulesInProf map[string]entityAndRuleTuple, + rulesInProf map[ruleTypeAndNamePair]entityAndRuleTuple, ) error { if rules == nil { return nil @@ -217,7 +226,9 @@ func createProfileRulesForEntity( EntityProfileID: entProf.ID, RuleTypeID: ruleID, }) - if err != nil { + if errors.Is(err, sql.ErrNoRows) { + log.Printf("the rule instantiation for rule already existed.") + } else if err != nil { log.Printf("error creating rule instantiation: %v", err) return status.Errorf(codes.Internal, "error creating profile") } @@ -423,7 +434,7 @@ func (s *Server) GetProfileStatusByName(ctx context.Context, return nil, err } - dbstat, err := s.store.GetProfileStatusByNameAndProject(ctx, db.GetProfileStatusByNameAndProjectParams{ + dbProfileStatus, err := s.store.GetProfileStatusByNameAndProject(ctx, db.GetProfileStatusByNameAndProjectParams{ ProjectID: entityCtx.Project.ID, Name: in.Name, }) @@ -434,10 +445,11 @@ func (s *Server) GetProfileStatusByName(ctx context.Context, return nil, status.Errorf(codes.Unknown, "failed to get profile: %s", err) } - var rulestats []*minderv1.RuleEvaluationStatus + var ruleEvaluationStatuses []*minderv1.RuleEvaluationStatus var selector *uuid.NullUUID var dbEntity *db.NullEntities - var rule *sql.NullString + var ruleType *sql.NullString + var ruleName *sql.NullString if in.GetAll() { selector = &uuid.NullUUID{} @@ -455,85 +467,112 @@ func (s *Server) GetProfileStatusByName(ctx context.Context, dbEntity = &db.NullEntities{Entities: entities.EntityTypeToDB(e.GetType()), Valid: true} } - if len(in.GetRule()) > 0 { - rule = &sql.NullString{String: in.GetRule(), Valid: true} + if len(in.GetRuleType()) > 0 { + ruleType = &sql.NullString{String: in.GetRuleType(), Valid: true} } else { - rule = &sql.NullString{Valid: false} + ruleType = &sql.NullString{Valid: false} + } + + if len(in.GetRuleName()) > 0 { + ruleName = &sql.NullString{String: in.GetRuleName(), Valid: true} + } else { + ruleName = &sql.NullString{Valid: false} } // TODO: Handle retrieving status for other types of entities if selector != nil { - dbrulestat, err := s.store.ListRuleEvaluationsByProfileId(ctx, db.ListRuleEvaluationsByProfileIdParams{ - ProfileID: dbstat.ID, - EntityID: *selector, - EntityType: *dbEntity, - RuleName: *rule, + dbRuleEvaluationStatuses, err := s.store.ListRuleEvaluationsByProfileId(ctx, db.ListRuleEvaluationsByProfileIdParams{ + ProfileID: dbProfileStatus.ID, + EntityID: *selector, + EntityType: *dbEntity, + RuleTypeName: *ruleType, + RuleName: *ruleName, }) if err != nil && !errors.Is(err, sql.ErrNoRows) { return nil, status.Errorf(codes.Unknown, "failed to list rule evaluation status: %s", err) } - rulestats = make([]*minderv1.RuleEvaluationStatus, 0, len(dbrulestat)) - for _, rs := range dbrulestat { - rs := rs - - var guidance string - - // make sure all fields are valid - if !rs.EvalStatus.Valid || !rs.EvalDetails.Valid || !rs.RemStatus.Valid || !rs.RemDetails.Valid || !rs.EvalLastUpdated.Valid { - log.Print("error rule evaluation value not valid") - continue - } - - if rs.EvalStatus.EvalStatusTypes == db.EvalStatusTypesFailure || rs.EvalStatus.EvalStatusTypes == db.EvalStatusTypesError { - ruleTypeInfo, err := s.store.GetRuleTypeByID(ctx, rs.RuleTypeID) - if err != nil { - log.Printf("error getting rule type info: %v", err) - } else { - guidance = ruleTypeInfo.Guidance - } - } - - st := &minderv1.RuleEvaluationStatus{ - ProfileId: dbstat.ID.String(), - RuleId: rs.RuleTypeID.String(), - RuleName: rs.RuleTypeName, - Entity: string(rs.Entity), - Status: string(rs.EvalStatus.EvalStatusTypes), - Details: rs.EvalDetails.String, - EntityInfo: getRuleEvalEntityInfo(ctx, s.store, dbEntity, selector, rs, entityCtx.Provider.Name), - Guidance: guidance, - LastUpdated: timestamppb.New(rs.EvalLastUpdated.Time), - RemediationStatus: string(rs.RemStatus.RemediationStatusTypes), - RemediationDetails: rs.RemDetails.String, - } - - if rs.RemLastUpdated.Valid { - st.RemediationLastUpdated = timestamppb.New(rs.RemLastUpdated.Time) - } - - rulestats = append(rulestats, st) - } - + ruleEvaluationStatuses = s.getRuleEvaluationStatuses( + ctx, dbRuleEvaluationStatuses, dbProfileStatus.ID.String(), + dbEntity, selector, entityCtx.Provider.Name, + ) // TODO: Add other entities once we have database entries for them } // Telemetry logging logger.BusinessRecord(ctx).Provider = entityCtx.Provider.Name logger.BusinessRecord(ctx).Project = entityCtx.Project.ID - logger.BusinessRecord(ctx).Profile = logger.Profile{Name: dbstat.Name, ID: dbstat.ID} + logger.BusinessRecord(ctx).Profile = logger.Profile{Name: dbProfileStatus.Name, ID: dbProfileStatus.ID} return &minderv1.GetProfileStatusByNameResponse{ ProfileStatus: &minderv1.ProfileStatus{ - ProfileId: dbstat.ID.String(), - ProfileName: dbstat.Name, - ProfileStatus: string(dbstat.ProfileStatus), - LastUpdated: timestamppb.New(dbstat.LastUpdated), + ProfileId: dbProfileStatus.ID.String(), + ProfileName: dbProfileStatus.Name, + ProfileStatus: string(dbProfileStatus.ProfileStatus), + LastUpdated: timestamppb.New(dbProfileStatus.LastUpdated), }, - RuleEvaluationStatus: rulestats, + RuleEvaluationStatus: ruleEvaluationStatuses, }, nil } +func (s *Server) getRuleEvaluationStatuses( + ctx context.Context, + dbRuleEvaluationStatuses []db.ListRuleEvaluationsByProfileIdRow, + profileId string, + dbEntity *db.NullEntities, + selector *uuid.NullUUID, + providerName string, +) []*minderv1.RuleEvaluationStatus { + ruleEvaluationStatuses := make( + []*minderv1.RuleEvaluationStatus, 0, len(dbRuleEvaluationStatuses), + ) + for _, dbRuleEvalStat := range dbRuleEvaluationStatuses { + var guidance string + + // make sure all fields are valid + if !dbRuleEvalStat.EvalStatus.Valid || + !dbRuleEvalStat.EvalDetails.Valid || + !dbRuleEvalStat.RemStatus.Valid || + !dbRuleEvalStat.RemDetails.Valid || + !dbRuleEvalStat.EvalLastUpdated.Valid { + log.Print("error rule evaluation value not valid") + continue + } + + if dbRuleEvalStat.EvalStatus.EvalStatusTypes == db.EvalStatusTypesFailure || + dbRuleEvalStat.EvalStatus.EvalStatusTypes == db.EvalStatusTypesError { + ruleTypeInfo, err := s.store.GetRuleTypeByID(ctx, dbRuleEvalStat.RuleTypeID) + if err != nil { + log.Printf("error getting rule type info: %v", err) + } else { + guidance = ruleTypeInfo.Guidance + } + } + + st := &minderv1.RuleEvaluationStatus{ + ProfileId: profileId, + RuleId: dbRuleEvalStat.RuleTypeID.String(), + RuleTypeName: dbRuleEvalStat.RuleTypeName, + RuleDescriptionName: dbRuleEvalStat.RuleName, + Entity: string(dbRuleEvalStat.Entity), + Status: string(dbRuleEvalStat.EvalStatus.EvalStatusTypes), + Details: dbRuleEvalStat.EvalDetails.String, + EntityInfo: getRuleEvalEntityInfo(ctx, s.store, dbEntity, selector, dbRuleEvalStat, providerName), + Guidance: guidance, + LastUpdated: timestamppb.New(dbRuleEvalStat.EvalLastUpdated.Time), + RemediationStatus: string(dbRuleEvalStat.RemStatus.RemediationStatusTypes), + RemediationDetails: dbRuleEvalStat.RemDetails.String, + } + + if dbRuleEvalStat.RemLastUpdated.Valid { + st.RemediationLastUpdated = timestamppb.New(dbRuleEvalStat.RemLastUpdated.Time) + } + + ruleEvaluationStatuses = append(ruleEvaluationStatuses, st) + } + return ruleEvaluationStatuses +} + // GetProfileStatusByProject is a method to get profile status for a project func (s *Server) GetProfileStatusByProject(ctx context.Context, _ *minderv1.GetProfileStatusByProjectRequest) (*minderv1.GetProfileStatusByProjectResponse, error) { @@ -638,6 +677,9 @@ func (s *Server) UpdateProfile(ctx context.Context, return nil, status.Errorf(codes.Internal, "error updating profile") } + // Adds default rule names, if not present + populateRuleNames(in) + oldProfile, err := getProfilePBFromDB(ctx, oldDBProfile.ID, entityCtx, qtx) if err != nil { if errors.Is(err, sql.ErrNoRows) || strings.Contains(err.Error(), "not found") { @@ -672,16 +714,19 @@ func (s *Server) UpdateProfile(ctx context.Context, minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS: in.GetBuildEnvironment(), minderv1.Entity_ENTITY_PULL_REQUESTS: in.GetPullRequest(), } { - if err := updateProfileRulesForEntity(ctx, ent, &profile, qtx, entRules, rules, oldRules); err != nil { + if err := updateProfileRulesForEntity(ctx, ent, &profile, qtx, entRules, rules); err != nil { return nil, err } } - if err := deleteUnusedRulesFromProfile(ctx, &profile, oldRules, qtx); err != nil { + unusedRuleStatuses := getUnusedOldRuleStatuses(rules, oldRules) + unusedRuleTypes := getUnusedOldRuleTypes(rules, oldRules) + + if err := deleteUnusedRulesFromProfile(ctx, &profile, unusedRuleTypes, qtx); err != nil { return nil, status.Errorf(codes.Internal, "error updating profile: %v", err) } - if err := deleteRuleStatusesForProfile(ctx, &profile, oldRules, qtx); err != nil { + if err := deleteRuleStatusesForProfile(ctx, &profile, unusedRuleStatuses, qtx); err != nil { return nil, status.Errorf(codes.Internal, "error updating profile: %v", err) } @@ -726,12 +771,17 @@ func (s *Server) getAndValidateRulesFromProfile( ctx context.Context, prof *minderv1.Profile, entityCtx engine.EntityContext, -) (map[string]entityAndRuleTuple, error) { +) (map[ruleTypeAndNamePair]entityAndRuleTuple, error) { // We capture the rule instantiations here so we can // track them in the db later. - rulesInProf := map[string]entityAndRuleTuple{} + rulesInProf := map[ruleTypeAndNamePair]entityAndRuleTuple{} - err := engine.TraverseAllRulesForPipeline(prof, func(r *minderv1.Profile_Rule) error { + err := validateRuleNameAndTypeInProfile(prof) + if err != nil { + return nil, err + } + + err = engine.TraverseAllRulesForPipeline(prof, func(r *minderv1.Profile_Rule) error { // TODO: This will need to be updated to support // the hierarchy tree once that's settled in. rtdb, err := s.store.GetRuleTypeByName(ctx, db.GetRuleTypeByNameParams{ @@ -768,7 +818,14 @@ func (s *Server) getAndValidateRulesFromProfile( return fmt.Errorf("error validating rule params: %w", err) } - rulesInProf[r.GetType()] = entityAndRuleTuple{ + ruleName := computeRuleName(r) + + key := ruleTypeAndNamePair{ + RuleType: r.GetType(), + RuleName: ruleName, + } + + rulesInProf[key] = entityAndRuleTuple{ Entity: minderv1.EntityFromString(rtyppb.Def.InEntity), RuleID: rtdb.ID, } @@ -787,10 +844,10 @@ func (s *Server) getRulesFromProfile( ctx context.Context, prof *minderv1.Profile, entityCtx engine.EntityContext, -) (map[string]entityAndRuleTuple, error) { +) (map[ruleTypeAndNamePair]entityAndRuleTuple, error) { // We capture the rule instantiations here so we can // track them in the db later. - rulesInProf := map[string]entityAndRuleTuple{} + rulesInProf := map[ruleTypeAndNamePair]entityAndRuleTuple{} err := engine.TraverseAllRulesForPipeline(prof, func(r *minderv1.Profile_Rule) error { // TODO: This will need to be updated to support @@ -809,13 +866,21 @@ func (s *Server) getRulesFromProfile( return fmt.Errorf("cannot convert rule type %s to pb: %w", rtdb.Name, err) } - rulesInProf[r.GetType()] = entityAndRuleTuple{ + ruleName := computeRuleName(r) + + key := ruleTypeAndNamePair{ + RuleType: r.GetType(), + RuleName: ruleName, + } + + rulesInProf[key] = entityAndRuleTuple{ Entity: minderv1.EntityFromString(rtyppb.Def.InEntity), RuleID: rtdb.ID, } return nil - }) + }, + ) if err != nil { return nil, err @@ -830,8 +895,7 @@ func updateProfileRulesForEntity( profile *db.Profile, qtx db.Querier, rules []*minderv1.Profile_Rule, - rulesInProf map[string]entityAndRuleTuple, - oldRulesInProf map[string]entityAndRuleTuple, + rulesInProf map[ruleTypeAndNamePair]entityAndRuleTuple, ) error { if len(rules) == 0 { return qtx.DeleteProfileForEntity(ctx, db.DeleteProfileForEntityParams{ @@ -872,10 +936,6 @@ func updateProfileRulesForEntity( log.Printf("error creating rule instantiation: %v", err) return status.Errorf(codes.Internal, "error updating profile") } - - // Remove the rule from the old rule IDs so we - // can delete the ones that are no longer needed - delete(oldRulesInProf, idx) } return err @@ -945,10 +1005,46 @@ func validateProfileUpdate(old *db.Profile, new *minderv1.Profile, entityCtx eng return nil } +func getUnusedOldRuleStatuses( + newRules, oldRules map[ruleTypeAndNamePair]entityAndRuleTuple, +) map[ruleTypeAndNamePair]entityAndRuleTuple { + unusedRuleStatuses := make(map[ruleTypeAndNamePair]entityAndRuleTuple) + + for ruleTypeAndName, rule := range oldRules { + if _, ok := newRules[ruleTypeAndName]; !ok { + unusedRuleStatuses[ruleTypeAndName] = rule + } + } + + return unusedRuleStatuses +} + +func getUnusedOldRuleTypes(newRules, oldRules map[ruleTypeAndNamePair]entityAndRuleTuple) []entityAndRuleTuple { + var unusedRuleTypes []entityAndRuleTuple + + oldRulesTypeMap := make(map[string]entityAndRuleTuple) + for ruleTypeAndName, rule := range oldRules { + oldRulesTypeMap[ruleTypeAndName.RuleType] = rule + } + + newRulesTypeMap := make(map[string]entityAndRuleTuple) + for ruleTypeAndName, rule := range newRules { + newRulesTypeMap[ruleTypeAndName.RuleType] = rule + } + + for ruleType, rule := range oldRulesTypeMap { + if _, ok := newRulesTypeMap[ruleType]; !ok { + unusedRuleTypes = append(unusedRuleTypes, rule) + } + } + + return unusedRuleTypes +} + func deleteUnusedRulesFromProfile( ctx context.Context, profile *db.Profile, - unusedRules map[string]entityAndRuleTuple, + unusedRules []entityAndRuleTuple, querier db.ExtendQuerier, ) error { for _, rule := range unusedRules { @@ -983,14 +1079,15 @@ func deleteUnusedRulesFromProfile( func deleteRuleStatusesForProfile( ctx context.Context, profile *db.Profile, - unusedRules map[string]entityAndRuleTuple, + unusedRuleStatuses map[ruleTypeAndNamePair]entityAndRuleTuple, querier db.ExtendQuerier, ) error { - for _, rule := range unusedRules { + for ruleTypeAndName, rule := range unusedRuleStatuses { log.Printf("deleting rule evaluations for rule %s in profile %s", rule.RuleID, profile.ID) if err := querier.DeleteRuleStatusesForProfileAndRuleType(ctx, db.DeleteRuleStatusesForProfileAndRuleTypeParams{ ProfileID: profile.ID, RuleTypeID: rule.RuleID, + RuleName: ruleTypeAndName.RuleName, }); err != nil { log.Printf("error deleting rule evaluations: %v", err) return fmt.Errorf("error deleting rule evaluations: %w", err) @@ -999,3 +1096,76 @@ func deleteRuleStatusesForProfile( return nil } + +func computeRuleName(rule *minderv1.Profile_Rule) string { + if rule.GetName() != "" { + return rule.GetName() + } + + return rule.GetType() +} + +func populateRuleNames(profile *minderv1.Profile) { + _ = engine.TraverseAllRulesForPipeline(profile, func(r *minderv1.Profile_Rule) error { + r.Name = computeRuleName(r) + return nil + }, + ) +} + +func validateRuleNameAndTypeInProfile(profile *minderv1.Profile) error { + for ent, entRules := range map[minderv1.Entity][]*minderv1.Profile_Rule{ + minderv1.Entity_ENTITY_REPOSITORIES: profile.GetRepository(), + minderv1.Entity_ENTITY_ARTIFACTS: profile.GetArtifact(), + minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS: profile.GetBuildEnvironment(), + minderv1.Entity_ENTITY_PULL_REQUESTS: profile.GetPullRequest(), + } { + if err := validateRuleNameAndType(ent, entRules); err != nil { + return err + } + } + + return nil +} + +func validateRuleNameAndType(entity minderv1.Entity, rules []*minderv1.Profile_Rule) error { + ruleNameToType := make(map[string]string) + emptyNameTypesSet := sets.New[string]() + for _, rule := range rules { + ruleName := rule.GetName() + ruleType := rule.GetType() + + if ruleName == ruleType { + return &engine.RuleValidationError{ + Err: fmt.Sprintf("cannot have rules with same name and type in entity '%s'", entity.ToString()), + RuleType: ruleType, + } + } + + if ruleName == "" { + if emptyNameTypesSet.Has(ruleType) { + return &engine.RuleValidationError{ + Err: fmt.Sprintf("cannot have rules with empty name and same type in entity '%s'", entity.ToString()), + RuleType: ruleType, + } + } + emptyNameTypesSet.Insert(ruleType) + } else { + if existingType, ok := ruleNameToType[ruleName]; ok { + if existingType == ruleType { + return &engine.RuleValidationError{ + Err: fmt.Sprintf("cannot have same rule types in entity '%s' with same name '%s'", entity.ToString(), ruleName), + RuleType: ruleType, + } + } + return &engine.RuleValidationError{ + Err: fmt.Sprintf("cannot have multiple rules in entity '%s' with same name '%s'", entity.ToString(), ruleName), + RuleType: ruleType, + } + + } + ruleNameToType[ruleName] = ruleType + } + } + return nil +} diff --git a/internal/controlplane/handlers_profile_test.go b/internal/controlplane/handlers_profile_test.go new file mode 100644 index 0000000000..a6f27fd4fb --- /dev/null +++ b/internal/controlplane/handlers_profile_test.go @@ -0,0 +1,290 @@ +// Copyright 2024 Stacklok, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controlplane + +import ( + "errors" + "reflect" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "github.com/stacklok/minder/internal/engine" + minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1" +) + +func TestValidateRuleNameAndType(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + entity minderv1.Entity + rules []*minderv1.Profile_Rule + wantErr bool + wantErrMsg string + }{ + { + name: "Valid rule names and types", + entity: minderv1.Entity_ENTITY_REPOSITORIES, + rules: []*minderv1.Profile_Rule{ + {Name: "rule1", Type: "type1"}, + {Name: "rule2", Type: "type2"}, + }, + wantErr: false, + }, + { + name: "Duplicate rule names with different types", + entity: minderv1.Entity_ENTITY_REPOSITORIES, + rules: []*minderv1.Profile_Rule{ + {Name: "rule1", Type: "type1"}, + {Name: "rule1", Type: "type2"}, + }, + wantErr: true, + wantErrMsg: "cannot have multiple rules in entity 'repository' with same name 'rule1'", + }, + { + name: "Rules with same rule names and rule type", + entity: minderv1.Entity_ENTITY_REPOSITORIES, + rules: []*minderv1.Profile_Rule{ + {Name: "rule1", Type: "type1"}, + {Name: "type1", Type: "type1"}, + }, + wantErr: true, + wantErrMsg: "cannot have rules with same name and type in entity 'repository'", + }, + { + name: "Duplicate rule names with same types", + entity: minderv1.Entity_ENTITY_REPOSITORIES, + rules: []*minderv1.Profile_Rule{ + {Name: "rule1", Type: "type1"}, + {Name: "rule1", Type: "type1"}, + }, + wantErr: true, + wantErrMsg: "cannot have same rule types in entity 'repository' with same name 'rule1'", + }, + { + name: "Empty rule names with same types", + entity: minderv1.Entity_ENTITY_REPOSITORIES, + rules: []*minderv1.Profile_Rule{ + {Name: "", Type: "type1"}, + {Name: "", Type: "type1"}, + }, + wantErr: true, + wantErrMsg: "cannot have rules with empty name and same type in entity 'repository'", + }, + { + name: "Multiple rules with empty names and different types", + entity: minderv1.Entity_ENTITY_ARTIFACTS, + rules: []*minderv1.Profile_Rule{ + {Name: "", Type: "type1"}, + {Name: "", Type: "type2"}, + {Name: "some name", Type: "type2"}, + {Name: "", Type: "type1"}, + }, + wantErr: true, + wantErrMsg: "cannot have rules with empty name and same type in entity 'artifact'", + }, + { + name: "Multiple rules with empty names and same types", + entity: minderv1.Entity_ENTITY_ARTIFACTS, + rules: []*minderv1.Profile_Rule{ + {Name: "", Type: "type1"}, + {Name: "some name 1", Type: "type1"}, + {Name: "some name 2", Type: "type1"}, + {Name: "some name 3", Type: "type1"}, + {Name: "", Type: "type1"}, + }, + wantErr: true, + wantErrMsg: "cannot have rules with empty name and same type in entity 'artifact'", + }, + { + name: "Multiple rules of same type but different names", + entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, + rules: []*minderv1.Profile_Rule{ + {Name: "", Type: "type1"}, + {Name: "rule1", Type: "type1"}, + {Name: "rule2", Type: "type1"}, + {Name: "rule3", Type: "type1"}, + {Name: "", Type: "type1"}, + {Name: "", Type: "type2"}, + {Name: "", Type: "type3"}, + }, + wantErr: true, + wantErrMsg: "cannot have rules with empty name and same type in entity 'build_environment'", + }, + } + + for _, test := range tests { + test := test + + t.Run(test.name, func(t *testing.T) { + t.Parallel() + err := validateRuleNameAndType(test.entity, test.rules) + + if test.wantErr { + require.Error(t, err) + + var v *engine.RuleValidationError + require.True(t, errors.As(err, &v)) + require.Equal(t, test.wantErrMsg, v.Err) + } + }) + } +} + +func TestGetUnusedOldRuleTypes(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + newRules map[ruleTypeAndNamePair]entityAndRuleTuple + oldRules map[ruleTypeAndNamePair]entityAndRuleTuple + wantUnused []entityAndRuleTuple + }{ + { + name: "Unused rule in oldRules", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type3", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + }, + wantUnused: []entityAndRuleTuple{ + {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + }, + }, + { + name: "Multiple unused rules in oldRules", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type3", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + {RuleType: "Type4", RuleName: "Name4"}: {Entity: minderv1.Entity_ENTITY_PULL_REQUESTS, RuleID: generateConsistentUUID(t, "Type4", "Name4")}, + }, + wantUnused: []entityAndRuleTuple{ + {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + {Entity: minderv1.Entity_ENTITY_PULL_REQUESTS, RuleID: generateConsistentUUID(t, "Type4", "Name4")}, + }, + }, + { + name: "No unused rules in oldRules", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + wantUnused: nil, + }, + { + name: "Unused rules with same rule type", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type1", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type1", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type1", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type1", "Name3")}, + }, + // All rule types are used + wantUnused: nil, + }, + } + + for _, test := range tests { + test := test + + t.Run(test.name, func(t *testing.T) { + t.Parallel() + unusedRuleTypes := getUnusedOldRuleTypes(test.newRules, test.oldRules) + require.ElementsMatch(t, test.wantUnused, unusedRuleTypes) + }) + } +} + +func TestGetUnusedOldRuleStatuses(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + newRules map[ruleTypeAndNamePair]entityAndRuleTuple + oldRules map[ruleTypeAndNamePair]entityAndRuleTuple + wantUnusedRules map[ruleTypeAndNamePair]entityAndRuleTuple + }{ + { + name: "Unused rule in oldRules", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type3", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + }, + wantUnusedRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type3", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type3", "Name3")}, + }, + }, + { + name: "No unused rules in oldRules", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type2", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type2", "Name2")}, + }, + wantUnusedRules: map[ruleTypeAndNamePair]entityAndRuleTuple{}, + }, + { + name: "Unused rules with same rule type", + newRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name1"}: {Entity: minderv1.Entity_ENTITY_REPOSITORIES, RuleID: generateConsistentUUID(t, "Type1", "Name1")}, + {RuleType: "Type1", RuleName: "Name2"}: {Entity: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS, RuleID: generateConsistentUUID(t, "Type1", "Name2")}, + }, + oldRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type1", "Name3")}, + }, + wantUnusedRules: map[ruleTypeAndNamePair]entityAndRuleTuple{ + {RuleType: "Type1", RuleName: "Name3"}: {Entity: minderv1.Entity_ENTITY_ARTIFACTS, RuleID: generateConsistentUUID(t, "Type1", "Name3")}, + }, + }, + } + + for _, test := range tests { + test := test + + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + gotUnusedRules := getUnusedOldRuleStatuses(test.newRules, test.oldRules) + require.True(t, reflect.DeepEqual(test.wantUnusedRules, gotUnusedRules)) + }) + } +} + +func generateConsistentUUID(t *testing.T, ruleType, ruleName string) uuid.UUID { + t.Helper() + return uuid.NewSHA1(uuid.Nil, []byte(ruleType+ruleName)) +} diff --git a/internal/db/models.go b/internal/db/models.go index 06b0739ec3..aeaa403e0f 100644 --- a/internal/db/models.go +++ b/internal/db/models.go @@ -471,6 +471,7 @@ type RuleEvaluation struct { RepositoryID uuid.NullUUID `json:"repository_id"` ArtifactID uuid.NullUUID `json:"artifact_id"` PullRequestID uuid.NullUUID `json:"pull_request_id"` + RuleName string `json:"rule_name"` } type RuleType struct { diff --git a/internal/db/profile_status.sql.go b/internal/db/profile_status.sql.go index 4a3669b3d4..9ef70c7b6a 100644 --- a/internal/db/profile_status.sql.go +++ b/internal/db/profile_status.sql.go @@ -20,18 +20,19 @@ const deleteRuleStatusesForProfileAndRuleType = `-- name: DeleteRuleStatusesForP DELETE FROM rule_evaluations WHERE id IN ( SELECT id FROM rule_evaluations as re - WHERE re.profile_id = $1 AND re.rule_type_id = $2 FOR UPDATE) + WHERE re.profile_id = $1 AND re.rule_type_id = $2 AND re.rule_name = $3 FOR UPDATE) ` type DeleteRuleStatusesForProfileAndRuleTypeParams struct { ProfileID uuid.UUID `json:"profile_id"` RuleTypeID uuid.UUID `json:"rule_type_id"` + RuleName string `json:"rule_name"` } // DeleteRuleStatusesForProfileAndRuleType deletes a rule evaluation // but locks the table before doing so. func (q *Queries) DeleteRuleStatusesForProfileAndRuleType(ctx context.Context, arg DeleteRuleStatusesForProfileAndRuleTypeParams) error { - _, err := q.db.ExecContext(ctx, deleteRuleStatusesForProfileAndRuleType, arg.ProfileID, arg.RuleTypeID) + _, err := q.db.ExecContext(ctx, deleteRuleStatusesForProfileAndRuleType, arg.ProfileID, arg.RuleTypeID, arg.RuleName) return err } @@ -177,6 +178,7 @@ SELECT ad.alert_last_updated, res.repository_id, res.entity, + res.rule_name, repo.repo_name, repo.repo_owner, repo.provider, @@ -199,13 +201,15 @@ WHERE res.profile_id = $1 AND ELSE false END ) AND (rt.name = $4 OR $4 IS NULL) + AND (res.rule_name = $5 OR $5 IS NULL) ` type ListRuleEvaluationsByProfileIdParams struct { - ProfileID uuid.UUID `json:"profile_id"` - EntityType NullEntities `json:"entity_type"` - EntityID uuid.NullUUID `json:"entity_id"` - RuleName sql.NullString `json:"rule_name"` + ProfileID uuid.UUID `json:"profile_id"` + EntityType NullEntities `json:"entity_type"` + EntityID uuid.NullUUID `json:"entity_id"` + RuleTypeName sql.NullString `json:"rule_type_name"` + RuleName sql.NullString `json:"rule_name"` } type ListRuleEvaluationsByProfileIdRow struct { @@ -221,6 +225,7 @@ type ListRuleEvaluationsByProfileIdRow struct { AlertLastUpdated sql.NullTime `json:"alert_last_updated"` RepositoryID uuid.NullUUID `json:"repository_id"` Entity Entities `json:"entity"` + RuleName string `json:"rule_name"` RepoName string `json:"repo_name"` RepoOwner string `json:"repo_owner"` Provider string `json:"provider"` @@ -233,6 +238,7 @@ func (q *Queries) ListRuleEvaluationsByProfileId(ctx context.Context, arg ListRu arg.ProfileID, arg.EntityType, arg.EntityID, + arg.RuleTypeName, arg.RuleName, ) if err != nil { @@ -255,6 +261,7 @@ func (q *Queries) ListRuleEvaluationsByProfileId(ctx context.Context, arg ListRu &i.AlertLastUpdated, &i.RepositoryID, &i.Entity, + &i.RuleName, &i.RepoName, &i.RepoOwner, &i.Provider, @@ -374,9 +381,9 @@ func (q *Queries) UpsertRuleDetailsRemediate(ctx context.Context, arg UpsertRule const upsertRuleEvaluations = `-- name: UpsertRuleEvaluations :one INSERT INTO rule_evaluations ( - profile_id, repository_id, artifact_id, pull_request_id, rule_type_id, entity -) VALUES ($1, $2, $3, $4, $5, $6) -ON CONFLICT (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), entity, rule_type_id) + profile_id, repository_id, artifact_id, pull_request_id, rule_type_id, entity, rule_name +) VALUES ($1, $2, $3, $4, $5, $6, $7) +ON CONFLICT (profile_id, repository_id, COALESCE(artifact_id, '00000000-0000-0000-0000-000000000000'::UUID), COALESCE(pull_request_id, '00000000-0000-0000-0000-000000000000'::UUID), entity, rule_type_id, rule_name) DO UPDATE SET profile_id = $1 RETURNING id ` @@ -388,6 +395,7 @@ type UpsertRuleEvaluationsParams struct { PullRequestID uuid.NullUUID `json:"pull_request_id"` RuleTypeID uuid.UUID `json:"rule_type_id"` Entity Entities `json:"entity"` + RuleName string `json:"rule_name"` } func (q *Queries) UpsertRuleEvaluations(ctx context.Context, arg UpsertRuleEvaluationsParams) (uuid.UUID, error) { @@ -398,6 +406,7 @@ func (q *Queries) UpsertRuleEvaluations(ctx context.Context, arg UpsertRuleEvalu arg.PullRequestID, arg.RuleTypeID, arg.Entity, + arg.RuleName, ) var id uuid.UUID err := row.Scan(&id) diff --git a/internal/db/store.go b/internal/db/store.go index e952fcf11b..2b38c33a69 100644 --- a/internal/db/store.go +++ b/internal/db/store.go @@ -27,7 +27,7 @@ import ( type ExtendQuerier interface { Querier GetRuleEvaluationByProfileIdAndRuleType(ctx context.Context, profileID uuid.UUID, entityType NullEntities, - entityID uuid.NullUUID, ruleName sql.NullString) (ListRuleEvaluationsByProfileIdRow, error) + ruleName sql.NullString, entityID uuid.NullUUID, ruleTypeName sql.NullString) (ListRuleEvaluationsByProfileIdRow, error) } // Store provides all functions to execute db queries and transactions @@ -84,14 +84,16 @@ func (q *Queries) GetRuleEvaluationByProfileIdAndRuleType( ctx context.Context, profileID uuid.UUID, entityType NullEntities, - entityID uuid.NullUUID, ruleName sql.NullString, + entityID uuid.NullUUID, + ruleTypeName sql.NullString, ) (ListRuleEvaluationsByProfileIdRow, error) { params := ListRuleEvaluationsByProfileIdParams{ - ProfileID: profileID, - EntityType: entityType, - EntityID: entityID, - RuleName: ruleName, + ProfileID: profileID, + EntityType: entityType, + EntityID: entityID, + RuleName: ruleName, + RuleTypeName: ruleTypeName, } res, err := q.ListRuleEvaluationsByProfileId(ctx, params) if err != nil { diff --git a/internal/engine/actions/alert/security_advisory/security_advisory.go b/internal/engine/actions/alert/security_advisory/security_advisory.go index 13a6698f08..1874703adb 100644 --- a/internal/engine/actions/alert/security_advisory/security_advisory.go +++ b/internal/engine/actions/alert/security_advisory/security_advisory.go @@ -72,7 +72,7 @@ To address this security exposure, we recommend taking the following actions: 2. In case Minder was not able to remediate this automatically, please refer to the guidance below to resolve the issue manually. ` // nolint:lll - tmplPart3Bottom = ` + tmplPart3BottomNoName = ` **Guidance** {{.Guidance}} @@ -86,18 +86,42 @@ To address this security exposure, we recommend taking the following actions: **About** +If you have any questions or believe that this evaluation is incorrect, please don't hesitate to reach out to the Minder team at info@stacklok.com. +` + // nolint:lll + tmplPart3BottomWithName = ` +**Guidance** + +{{.Guidance}} + +**Details** + +- Profile: {{.Profile}} +- Rule: {{.Rule}} +- Name: {{.Name}} +- Repository: {{.Repository}} +- Severity: {{.Severity}} + +**About** + If you have any questions or believe that this evaluation is incorrect, please don't hesitate to reach out to the Minder team at info@stacklok.com. ` ) // Alert is the structure backing the security-advisory alert action type Alert struct { - actionType interfaces.ActionType - cli provifv1.GitHub - saCfg *pb.RuleType_Definition_Alert_AlertTypeSA - summaryTmpl *htmltemplate.Template - descriptionTmpl *htmltemplate.Template - descriptionNoRemTmpl *htmltemplate.Template + actionType interfaces.ActionType + cli provifv1.GitHub + saCfg *pb.RuleType_Definition_Alert_AlertTypeSA + summaryTmpl *htmltemplate.Template + descriptionOptions *descriptionOptions +} + +type descriptionOptions struct { + withRemWithNameTmpl *htmltemplate.Template + withRemNoNameTmpl *htmltemplate.Template + noRemWithNameTmpl *htmltemplate.Template + noRemNoNameTmpl *htmltemplate.Template } type paramsSA struct { @@ -118,7 +142,9 @@ type templateParamsSA struct { Severity string Guidance string RuleRemediation string + Name string } + type alertMetadata struct { ID string `json:"ghsa_id,omitempty"` } @@ -132,34 +158,31 @@ func NewSecurityAdvisoryAlert( if actionType == "" { return nil, fmt.Errorf("action type cannot be empty") } + // Parse the templates for summary and description sumT, err := htmltemplate.New(tmplSummaryName).Option("missingkey=error").Parse(tmplSummary) if err != nil { return nil, fmt.Errorf("cannot parse summary template: %w", err) } - descriptionTmplNoRemStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleNoRem, tmplPart3Bottom}, "\n") - descNoRemT, err := htmltemplate.New(tmplDescriptionNameNoRem).Option("missingkey=error").Parse(descriptionTmplNoRemStr) - if err != nil { - return nil, fmt.Errorf("cannot parse description template: %w", err) - } - descriptionTmplStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleRem, tmplPart3Bottom}, "\n") - descT, err := htmltemplate.New(tmplDescriptionNameRem).Option("missingkey=error").Parse(descriptionTmplStr) - if err != nil { - return nil, fmt.Errorf("cannot parse description template: %w", err) - } + // Get the GitHub client cli, err := pbuild.GetGitHub(context.Background()) if err != nil { return nil, fmt.Errorf("cannot get http client: %w", err) } + + descOptions, err := getDescriptionOptions() + if err != nil { + return nil, fmt.Errorf("cannot get description options: %w", err) + } + // Create the alert action return &Alert{ - actionType: actionType, - cli: cli, - saCfg: saCfg, - summaryTmpl: sumT, - descriptionTmpl: descT, - descriptionNoRemTmpl: descNoRemT, + actionType: actionType, + cli: cli, + saCfg: saCfg, + summaryTmpl: sumT, + descriptionOptions: descOptions, }, nil } @@ -344,6 +367,9 @@ func (alert *Alert) getParamsForSecurityAdvisory( result.Template.Rule = params.GetRuleType().Name // Get the profile name result.Template.Profile = params.GetProfile().Name + // Get the rule name + result.Template.Name = params.GetRule().Name + // Check if remediation is available for the rule type if params.GetRuleType().Def.Remediate != nil { result.Template.RuleRemediation = "already available" @@ -357,16 +383,67 @@ func (alert *Alert) getParamsForSecurityAdvisory( } result.Summary = summaryStr.String() + descriptionStr, err := alert.executeDescriptionTemplate(params, result) + if err != nil { + return nil, fmt.Errorf("error executing description template: %w", err) + } + result.Description = descriptionStr.String() + return result, nil +} + +func (alert *Alert) executeDescriptionTemplate(params interfaces.ActionsParams, result *paramsSA) (*strings.Builder, error) { + var err error var descriptionStr strings.Builder - // Get the description template depending if remediation is available + if interfaces.ActionOptFromString(params.GetProfile().Remediate, interfaces.ActionOptOff) == interfaces.ActionOptOn { - err = alert.descriptionTmpl.Execute(&descriptionStr, result.Template) + if result.Template.Rule == result.Template.Name { + err = alert.descriptionOptions.withRemNoNameTmpl.Execute(&descriptionStr, result.Template) + } else { + // Only show name if it's different from the rule name + err = alert.descriptionOptions.withRemWithNameTmpl.Execute(&descriptionStr, result.Template) + } } else { - err = alert.descriptionNoRemTmpl.Execute(&descriptionStr, result.Template) + if result.Template.Rule == result.Template.Name { + err = alert.descriptionOptions.noRemNoNameTmpl.Execute(&descriptionStr, result.Template) + } else { + // Only show name if it's different from the rule name + err = alert.descriptionOptions.noRemWithNameTmpl.Execute(&descriptionStr, result.Template) + } } + return &descriptionStr, err +} + +func getDescriptionOptions() (*descriptionOptions, error) { + cannotParseErr := "cannot parse description template: %w" + + withRemWithNameStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleRem, tmplPart3BottomWithName}, "\n") + withRemWithNameT, err := htmltemplate.New(tmplDescriptionNameRem).Option("missingkey=error").Parse(withRemWithNameStr) if err != nil { - return nil, fmt.Errorf("error executing description template: %w", err) + return nil, fmt.Errorf(cannotParseErr, err) } - result.Description = descriptionStr.String() - return result, nil + + withRemNoNameStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleRem, tmplPart3BottomNoName}, "\n") + withRemNoNameT, err := htmltemplate.New(tmplDescriptionNameRem).Option("missingkey=error").Parse(withRemNoNameStr) + if err != nil { + return nil, fmt.Errorf(cannotParseErr, err) + } + + noRemWithNameStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleNoRem, tmplPart3BottomWithName}, "\n") + noRemWithNameT, err := htmltemplate.New(tmplDescriptionNameNoRem).Option("missingkey=error").Parse(noRemWithNameStr) + if err != nil { + return nil, fmt.Errorf(cannotParseErr, err) + } + + noRemNoNameStr := strings.Join([]string{tmplPart1Top, tmplPart2MiddleNoRem, tmplPart3BottomNoName}, "\n") + noRemNoNameT, err := htmltemplate.New(tmplDescriptionNameNoRem).Option("missingkey=error").Parse(noRemNoNameStr) + if err != nil { + return nil, fmt.Errorf(cannotParseErr, err) + } + + return &descriptionOptions{ + withRemWithNameTmpl: withRemWithNameT, + withRemNoNameTmpl: withRemNoNameT, + noRemWithNameTmpl: noRemWithNameT, + noRemNoNameTmpl: noRemNoNameT, + }, nil } diff --git a/internal/engine/eval_status.go b/internal/engine/eval_status.go index c794badf42..2f4fff8807 100644 --- a/internal/engine/eval_status.go +++ b/internal/engine/eval_status.go @@ -73,17 +73,23 @@ func (e *Executor) createEvalStatusParams( return nil, fmt.Errorf("build environment entity type not supported") } - ruleName := sql.NullString{ + ruleTypeName := sql.NullString{ String: rule.Type, Valid: true, } + ruleName := sql.NullString{ + String: rule.Name, + Valid: true, + } + // Get the current rule evaluation from the database evalStatus, err := e.querier.GetRuleEvaluationByProfileIdAndRuleType(ctx, params.ProfileID, entityType, - entityID, ruleName, + entityID, + ruleTypeName, ) if err != nil { return nil, fmt.Errorf("error getting rule evaluation status from db: %w", err) @@ -127,6 +133,7 @@ func (e *Executor) createOrUpdateEvalStatus( Entity: params.EntityType, RuleTypeID: params.RuleTypeID, PullRequestID: params.PullRequestID, + RuleName: params.Rule.Name, }) if err != nil { diff --git a/internal/engine/executor_test.go b/internal/engine/executor_test.go index bfdb7a8fc0..d87f0906c6 100644 --- a/internal/engine/executor_test.go +++ b/internal/engine/executor_test.go @@ -96,6 +96,7 @@ func TestExecutor_handleEntityEvent(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), ).Return(db.ListRuleEvaluationsByProfileIdRow{}, nil) // get project information @@ -132,6 +133,7 @@ func TestExecutor_handleEntityEvent(t *testing.T) { crs := []*minderv1.Profile_Rule{ { Type: passthroughRuleType, + Name: passthroughRuleType, Def: &structpb.Struct{}, }, } @@ -203,6 +205,7 @@ default allow = true`, ArtifactID: uuid.NullUUID{}, RuleTypeID: ruleTypeID, Entity: db.EntitiesRepository, + RuleName: passthroughRuleType, }).Return(ruleEvalId, nil) // Mock upserting eval details status diff --git a/pkg/api/openapi/minder/v1/minder.swagger.json b/pkg/api/openapi/minder/v1/minder.swagger.json index 92d95c8550..d7bc5e5e6d 100644 --- a/pkg/api/openapi/minder/v1/minder.swagger.json +++ b/pkg/api/openapi/minder/v1/minder.swagger.json @@ -846,7 +846,13 @@ "type": "boolean" }, { - "name": "rule", + "name": "ruleType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "ruleName", "in": "query", "required": false, "type": "string" @@ -2231,6 +2237,10 @@ "def": { "type": "object", "description": "def is the definition of the rule.\nThis depends on the rule type." + }, + "name": { + "type": "string", + "title": "name is the descriptive name of the rule, not to be confused with type" } }, "description": "Rule defines the individual call of a certain rule type." @@ -3122,10 +3132,6 @@ "type": "string", "title": "rule_id is the id of the rule" }, - "ruleName": { - "type": "string", - "title": "rule_name is the name of the rule" - }, "entity": { "type": "string", "title": "entity is the entity that was evaluated" @@ -3166,6 +3172,14 @@ "remediationDetails": { "type": "string", "title": "remediation_details is the description of the remediation attempt if any" + }, + "ruleTypeName": { + "type": "string", + "title": "rule_type_name is the name of the rule" + }, + "ruleDescriptionName": { + "type": "string", + "title": "rule_description_name is the name to describe the rule" } }, "title": "get the status of the rules for a given profile" diff --git a/pkg/api/protobuf/go/minder/v1/minder.pb.go b/pkg/api/protobuf/go/minder/v1/minder.pb.go index 39b1a3f895..5ddd05c5b3 100644 --- a/pkg/api/protobuf/go/minder/v1/minder.pb.go +++ b/pkg/api/protobuf/go/minder/v1/minder.pb.go @@ -3898,8 +3898,6 @@ type RuleEvaluationStatus struct { ProfileId string `protobuf:"bytes,1,opt,name=profile_id,json=profileId,proto3" json:"profile_id,omitempty"` // rule_id is the id of the rule RuleId string `protobuf:"bytes,2,opt,name=rule_id,json=ruleId,proto3" json:"rule_id,omitempty"` - // rule_name is the name of the rule - RuleName string `protobuf:"bytes,3,opt,name=rule_name,json=ruleName,proto3" json:"rule_name,omitempty"` // entity is the entity that was evaluated Entity string `protobuf:"bytes,4,opt,name=entity,proto3" json:"entity,omitempty"` // status is the status of the evaluation @@ -3918,6 +3916,10 @@ type RuleEvaluationStatus struct { RemediationLastUpdated *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=remediation_last_updated,json=remediationLastUpdated,proto3,oneof" json:"remediation_last_updated,omitempty"` // remediation_details is the description of the remediation attempt if any RemediationDetails string `protobuf:"bytes,12,opt,name=remediation_details,json=remediationDetails,proto3" json:"remediation_details,omitempty"` + // rule_type_name is the name of the rule + RuleTypeName string `protobuf:"bytes,13,opt,name=rule_type_name,json=ruleTypeName,proto3" json:"rule_type_name,omitempty"` + // rule_description_name is the name to describe the rule + RuleDescriptionName string `protobuf:"bytes,14,opt,name=rule_description_name,json=ruleDescriptionName,proto3" json:"rule_description_name,omitempty"` } func (x *RuleEvaluationStatus) Reset() { @@ -3966,13 +3968,6 @@ func (x *RuleEvaluationStatus) GetRuleId() string { return "" } -func (x *RuleEvaluationStatus) GetRuleName() string { - if x != nil { - return x.RuleName - } - return "" -} - func (x *RuleEvaluationStatus) GetEntity() string { if x != nil { return x.Entity @@ -4036,6 +4031,20 @@ func (x *RuleEvaluationStatus) GetRemediationDetails() string { return "" } +func (x *RuleEvaluationStatus) GetRuleTypeName() string { + if x != nil { + return x.RuleTypeName + } + return "" +} + +func (x *RuleEvaluationStatus) GetRuleDescriptionName() string { + if x != nil { + return x.RuleDescriptionName + } + return "" +} + type GetProfileStatusByNameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4044,10 +4053,11 @@ type GetProfileStatusByNameRequest struct { // context is the context in which the rule type is evaluated. Context *Context `protobuf:"bytes,1,opt,name=context,proto3" json:"context,omitempty"` // name is the name of the profile to get - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Entity *GetProfileStatusByNameRequest_EntityTypedId `protobuf:"bytes,3,opt,name=entity,proto3" json:"entity,omitempty"` - All bool `protobuf:"varint,4,opt,name=all,proto3" json:"all,omitempty"` - Rule string `protobuf:"bytes,5,opt,name=rule,proto3" json:"rule,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Entity *GetProfileStatusByNameRequest_EntityTypedId `protobuf:"bytes,3,opt,name=entity,proto3" json:"entity,omitempty"` + All bool `protobuf:"varint,4,opt,name=all,proto3" json:"all,omitempty"` + RuleType string `protobuf:"bytes,6,opt,name=rule_type,json=ruleType,proto3" json:"rule_type,omitempty"` + RuleName string `protobuf:"bytes,7,opt,name=rule_name,json=ruleName,proto3" json:"rule_name,omitempty"` } func (x *GetProfileStatusByNameRequest) Reset() { @@ -4110,9 +4120,16 @@ func (x *GetProfileStatusByNameRequest) GetAll() bool { return false } -func (x *GetProfileStatusByNameRequest) GetRule() string { +func (x *GetProfileStatusByNameRequest) GetRuleType() string { + if x != nil { + return x.RuleType + } + return "" +} + +func (x *GetProfileStatusByNameRequest) GetRuleName() string { if x != nil { - return x.Rule + return x.RuleName } return "" } @@ -6932,6 +6949,8 @@ type Profile_Rule struct { // def is the definition of the rule. // This depends on the rule type. Def *structpb.Struct `protobuf:"bytes,3,opt,name=def,proto3" json:"def,omitempty"` + // name is the descriptive name of the rule, not to be confused with type + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } func (x *Profile_Rule) Reset() { @@ -6987,6 +7006,13 @@ func (x *Profile_Rule) GetDef() *structpb.Struct { return nil } +func (x *Profile_Rule) GetName() string { + if x != nil { + return x.Name + } + return "" +} + var file_minder_v1_minder_proto_extTypes = []protoimpl.ExtensionInfo{ { ExtendedType: (*descriptorpb.MethodOptions)(nil), @@ -7532,65 +7558,73 @@ var file_minder_v1_minder_proto_rawDesc = []byte{ 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x22, 0xf9, 0x04, 0x0a, 0x14, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x61, + 0x61, 0x74, 0x65, 0x64, 0x22, 0xc7, 0x05, 0x0a, 0x14, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x75, 0x6c, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x12, 0x50, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, - 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x67, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x67, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x59, 0x0a, 0x18, 0x72, 0x65, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x16, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, - 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x22, 0x9f, 0x02, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x64, 0x49, 0x64, 0x52, 0x06, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x1a, 0x46, 0x0a, 0x0d, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x64, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x69, 0x6e, 0x64, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x22, 0xb8, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x67, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x12, + 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x59, 0x0a, 0x18, 0x72, + 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x16, 0x72, 0x65, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6c, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x72, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, + 0x15, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x75, + 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, + 0x65, 0x1a, 0x3d, 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, + 0x03, 0x10, 0x04, 0x52, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xd1, + 0x02, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2c, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x64, 0x49, 0x64, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x46, + 0x0a, 0x0d, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x64, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, + 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x52, 0x04, 0x72, 0x75, + 0x6c, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, @@ -7901,7 +7935,7 @@ var file_minder_v1_minder_proto_rawDesc = []byte{ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0xd3, 0x04, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0xe8, 0x04, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, @@ -7929,342 +7963,343 @@ var file_minder_v1_minder_proto_rawDesc = []byte{ 0x28, 0x09, 0x48, 0x02, 0x52, 0x05, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x76, 0x0a, 0x04, - 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x29, 0x0a, 0x03, 0x64, 0x65, 0x66, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, - 0x03, 0x64, 0x65, 0x66, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x61, 0x6c, - 0x65, 0x72, 0x74, 0x2a, 0x7b, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x77, 0x6e, - 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x57, 0x4e, - 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1d, 0x0a, 0x19, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, - 0x18, 0x0a, 0x14, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, - 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x42, 0x4a, - 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, - 0x2a, 0x72, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x45, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, 0x59, 0x53, 0x54, 0x45, - 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x15, 0x0a, 0x11, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, - 0x5f, 0x4e, 0x50, 0x4d, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, - 0x4f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x47, 0x4f, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, - 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x50, 0x59, - 0x50, 0x49, 0x10, 0x03, 0x2a, 0x88, 0x01, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, - 0x16, 0x0a, 0x12, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x54, 0x49, 0x54, - 0x59, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x45, 0x53, 0x10, 0x01, - 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, - 0x5f, 0x45, 0x4e, 0x56, 0x49, 0x52, 0x4f, 0x4e, 0x4d, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, - 0x14, 0x0a, 0x10, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, - 0x43, 0x54, 0x53, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, - 0x50, 0x55, 0x4c, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x10, 0x04, 0x32, - 0x7d, 0x0a, 0x0d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x6c, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, - 0x1d, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, - 0xaa, 0xf8, 0x18, 0x04, 0x08, 0x01, 0x10, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x32, 0xb3, - 0x03, 0x0a, 0x0f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x5a, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x12, 0x7d, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x12, 0x21, 0x2e, 0x6d, 0x69, - 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, - 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x23, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, - 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x8a, 0x01, 0x0a, + 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x29, 0x0a, 0x03, 0x64, 0x65, + 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x52, 0x03, 0x64, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, + 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x72, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x42, 0x08, + 0x0a, 0x06, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2a, 0x7b, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x42, 0x4a, 0x45, 0x43, + 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, + 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4f, + 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x55, + 0x53, 0x45, 0x52, 0x10, 0x03, 0x2a, 0x72, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x45, 0x63, 0x6f, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, + 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, + 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x4e, 0x50, 0x4d, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x44, + 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x47, 0x4f, 0x10, + 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x50, 0x5f, 0x45, 0x43, 0x4f, 0x53, 0x59, 0x53, 0x54, + 0x45, 0x4d, 0x5f, 0x50, 0x59, 0x50, 0x49, 0x10, 0x03, 0x2a, 0x88, 0x01, 0x0a, 0x06, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, + 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, + 0x49, 0x45, 0x53, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, + 0x42, 0x55, 0x49, 0x4c, 0x44, 0x5f, 0x45, 0x4e, 0x56, 0x49, 0x52, 0x4f, 0x4e, 0x4d, 0x45, 0x4e, + 0x54, 0x53, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x41, + 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x53, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x4e, + 0x54, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x4c, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, + 0x54, 0x53, 0x10, 0x04, 0x32, 0x7d, 0x0a, 0x0d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1d, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1e, 0xaa, 0xf8, 0x18, 0x04, 0x08, 0x01, 0x10, 0x01, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x32, 0xb3, 0x03, 0x0a, 0x0f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0xaa, 0xf8, + 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x5a, 0x13, 0x12, 0x11, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, + 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x12, 0x7d, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x12, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8a, 0x01, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, - 0x61, 0x6d, 0x65, 0x7d, 0x32, 0xbf, 0x05, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x4c, 0x12, 0x25, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0xaa, 0xf8, - 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x75, 0x72, 0x6c, 0x12, 0xab, - 0x01, 0x0a, 0x17, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x46, - 0x6f, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x4c, 0x49, 0x12, 0x29, 0x2e, 0x6d, 0x69, 0x6e, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, - 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x4c, 0x49, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x4f, 0xaa, 0xf8, 0x18, - 0x02, 0x08, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x5a, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0xaa, + 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x32, 0xbf, 0x05, 0x0a, 0x0c, 0x4f, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x13, 0x47, + 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, + 0x52, 0x4c, 0x12, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, + 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x20, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, + 0x75, 0x72, 0x6c, 0x12, 0xab, 0x01, 0x0a, 0x17, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x4c, 0x49, 0x12, + 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x43, 0x4c, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79, + 0x22, 0x4f, 0xaa, 0xf8, 0x18, 0x02, 0x08, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x5a, 0x1b, + 0x12, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x6c, 0x69, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, - 0x63, 0x6b, 0x2f, 0x63, 0x6c, 0x69, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x7b, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x63, 0x6c, 0x69, 0x12, 0xa7, 0x01, 0x0a, - 0x12, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x64, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x44, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, 0x3a, 0x01, - 0x2a, 0x5a, 0x14, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, - 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, - 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0xcd, 0x01, 0x0a, 0x17, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x72, - 0x6f, 0x6d, 0x12, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x63, 0x6b, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x63, 0x6c, + 0x69, 0x12, 0xa7, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x38, 0x3a, 0x01, 0x2a, 0x5a, 0x14, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0xcd, 0x01, 0x0a, 0x17, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x72, 0x6f, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0xaa, 0xf8, 0x18, 0x02, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f, 0x7b, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x7d, 0x12, 0x2a, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f, - 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x7d, 0x32, 0xd4, 0x0a, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xc4, 0x01, 0x0a, - 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x64, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x61, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x53, - 0x3a, 0x01, 0x2a, 0x5a, 0x1d, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, - 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x12, 0xf1, 0x01, 0x0a, 0x22, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x46, 0x72, - 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x6d, 0x69, 0x6e, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, - 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x35, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x65, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, + 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x5a, 0x21, 0x12, 0x1f, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x7d, 0x12, + 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, + 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x7d, 0x32, 0xd4, 0x0a, 0x0a, 0x11, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0xc4, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x53, 0x3a, 0x01, 0x2a, 0x5a, 0x1d, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0xf1, 0x01, 0x0a, 0x22, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2f, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, - 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0xab, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x6d, - 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x42, 0x5a, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x28, 0x2f, 0x61, 0x70, + 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x34, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0xaa, 0xf8, + 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x5a, 0x1d, 0x12, 0x1b, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x12, 0x23, 0x2e, 0x6d, 0x69, - 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0xab, 0x01, 0x0a, + 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, + 0x73, 0x12, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0xaa, 0xf8, 0x18, 0x02, + 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x5a, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x28, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, + 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, + 0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xc8, 0x01, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x69, 0x6e, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x62, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x56, - 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, - 0x65, 0x7d, 0x12, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, - 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, - 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x12, - 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x35, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, - 0x2a, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xd3, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, - 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0xaa, 0xf8, 0x18, + 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x69, 0x64, + 0x2f, 0x7b, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0xc8, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x56, 0x5a, 0x20, 0x2a, 0x1e, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6e, 0x61, - 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2a, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x32, 0xc0, 0x02, - 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, - 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x69, - 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x69, 0x6e, 0x64, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, - 0x28, 0x03, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x22, 0x0c, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x0a, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x03, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, - 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x19, 0x2e, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x56, 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6e, 0x61, 0x6d, 0x65, + 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, + 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x14, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x79, 0x49, 0x64, 0x12, 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, + 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x2a, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xd3, 0x01, 0x0a, + 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0xaa, 0xf8, + 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x56, 0x5a, 0x20, 0x2a, 0x1e, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2a, 0x32, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x7b, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, + 0x65, 0x7d, 0x32, 0xc0, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x12, 0x1c, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xaa, + 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x03, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, + 0x22, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x12, 0x67, + 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, + 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x69, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0xaa, 0xf8, 0x18, 0x04, 0x18, + 0x01, 0x28, 0x03, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x03, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, - 0x32, 0xa4, 0x0d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, 0x0f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x6d, - 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x22, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, - 0x01, 0x2a, 0x1a, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x78, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x2a, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x6f, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1e, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, - 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x79, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x64, - 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, - 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0xaa, 0xf8, 0x18, 0x02, 0x28, - 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, - 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x19, - 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2b, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0xaa, 0xf8, 0x18, 0x02, 0x28, + 0x03, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x75, 0x73, 0x65, 0x72, 0x32, 0xa4, 0x0d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xaa, 0xf8, + 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, + 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x76, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x1a, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x78, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, + 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x2a, 0x14, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x69, + 0x64, 0x7d, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1e, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x12, 0x79, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, + 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xaa, 0xf8, 0x18, 0x02, + 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9f, + 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x74, 0x0a, 0x0d, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x69, - 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, - 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, - 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x8b, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x69, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, + 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x9c, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2b, + 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x69, + 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x02, 0x28, + 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x74, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x1f, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x20, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x8b, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2b, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, - 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x7e, - 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x49, - 0x64, 0x12, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x7b, - 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x7b, 0x0a, 0x0e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x2e, - 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x1a, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, - 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, - 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x26, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, - 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x58, 0x0a, 0x0b, 0x72, 0x70, 0x63, 0x5f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x85, 0x8f, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x70, 0x63, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x72, 0x70, 0x63, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6c, 0x6f, 0x6b, 0x2f, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2f, - 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x70, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0xaa, 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, + 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, + 0x6d, 0x65, 0x7d, 0x12, 0x7e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x79, + 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, + 0xf8, 0x18, 0x02, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0x7b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x04, + 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x7b, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, + 0x02, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x1a, 0x11, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x7d, 0x0a, + 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x20, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0xaa, 0xf8, 0x18, 0x04, 0x18, 0x01, 0x28, 0x02, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, + 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x58, 0x0a, 0x0b, + 0x72, 0x70, 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x85, 0x8f, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x70, 0x63, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x72, 0x70, 0x63, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6c, 0x6f, 0x6b, 0x2f, 0x6d, 0x69, + 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x2f, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/minder/v1/minder.proto b/proto/minder/v1/minder.proto index 3f5e4f1051..45b93ead59 100644 --- a/proto/minder/v1/minder.proto +++ b/proto/minder/v1/minder.proto @@ -839,12 +839,13 @@ message ProfileStatus { // get the status of the rules for a given profile message RuleEvaluationStatus { + reserved 3; + reserved "rule_name"; + // profile_id is the id of the profile string profile_id = 1; // rule_id is the id of the rule string rule_id = 2; - // rule_name is the name of the rule - string rule_name = 3; // entity is the entity that was evaluated string entity = 4; // status is the status of the evaluation @@ -863,9 +864,16 @@ message RuleEvaluationStatus { optional google.protobuf.Timestamp remediation_last_updated = 11; // remediation_details is the description of the remediation attempt if any string remediation_details = 12; + // rule_type_name is the name of the rule + string rule_type_name = 13; + // rule_description_name is the name to describe the rule + string rule_description_name = 14; } message GetProfileStatusByNameRequest { + reserved 5; + reserved "rule"; + // context is the context in which the rule type is evaluated. Context context = 1; // name is the name of the profile to get @@ -883,7 +891,8 @@ message GetProfileStatusByNameRequest { EntityTypedId entity = 3; bool all = 4; - string rule = 5; + string rule_type = 6; + string rule_name = 7; } message GetProfileStatusByNameResponse { @@ -1306,6 +1315,9 @@ message Profile { // def is the definition of the rule. // This depends on the rule type. google.protobuf.Struct def = 3; + + // name is the descriptive name of the rule, not to be confused with type + string name = 4; } // These are the entities that one could set in the profile.