mirror of https://github.com/harness/drone.git
214 lines
5.3 KiB
Go
214 lines
5.3 KiB
Go
// Copyright 2023 Harness, 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 types
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/harness/gitness/types/enum"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Rule struct {
|
|
ID int64 `json:"-"`
|
|
Version int64 `json:"-"`
|
|
|
|
CreatedBy int64 `json:"-"`
|
|
Created int64 `json:"created"`
|
|
Updated int64 `json:"updated"`
|
|
|
|
RepoID *int64 `json:"-"`
|
|
SpaceID *int64 `json:"-"`
|
|
|
|
Identifier string `json:"identifier"`
|
|
Description string `json:"description"`
|
|
|
|
Type RuleType `json:"type"`
|
|
State enum.RuleState `json:"state"`
|
|
|
|
Pattern json.RawMessage `json:"pattern"`
|
|
Definition json.RawMessage `json:"definition"`
|
|
|
|
CreatedByInfo PrincipalInfo `json:"created_by"`
|
|
|
|
Users map[int64]*PrincipalInfo `json:"users"`
|
|
UserGroups map[int64]*UserGroupInfo `json:"user_groups"`
|
|
}
|
|
|
|
// TODO [CODE-1363]: remove after identifier migration.
|
|
func (r Rule) MarshalJSON() ([]byte, error) {
|
|
// alias allows us to embed the original object while avoiding an infinite loop of marshaling.
|
|
type alias Rule
|
|
return json.Marshal(&struct {
|
|
alias
|
|
UID string `json:"uid"`
|
|
}{
|
|
alias: (alias)(r),
|
|
UID: r.Identifier,
|
|
})
|
|
}
|
|
|
|
func (r Rule) MarshalYAML() (interface{}, error) {
|
|
// yaml cannot marshal json.RawMessage
|
|
pattern := make(map[string]any)
|
|
err := yaml.Unmarshal(r.Pattern, pattern)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
definition := make(map[string]any)
|
|
err = yaml.Unmarshal(r.Definition, definition)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return map[string]any{
|
|
"id": r.ID,
|
|
"created": r.Created,
|
|
"updated": r.Updated,
|
|
"created_by": r.CreatedBy,
|
|
"identifier": r.Identifier,
|
|
"description": r.Description,
|
|
"type": r.Type,
|
|
"state": r.State,
|
|
"pattern": pattern,
|
|
"definition": definition,
|
|
}, nil
|
|
}
|
|
|
|
// Clone makes deep copy of the rule object.
|
|
func (r Rule) Clone() Rule {
|
|
var repoID *int64
|
|
var spaceID *int64
|
|
|
|
if r.RepoID != nil {
|
|
id := *r.RepoID
|
|
repoID = &id
|
|
}
|
|
|
|
if r.SpaceID != nil {
|
|
id := *r.SpaceID
|
|
spaceID = &id
|
|
}
|
|
|
|
r.RepoID = repoID
|
|
r.SpaceID = spaceID
|
|
|
|
pattern := make(json.RawMessage, len(r.Pattern))
|
|
copy(pattern, r.Pattern)
|
|
r.Pattern = pattern
|
|
|
|
definition := make(json.RawMessage, len(r.Definition))
|
|
copy(definition, r.Definition)
|
|
r.Definition = definition
|
|
|
|
users := make(map[int64]*PrincipalInfo, len(r.Users))
|
|
for key, value := range r.Users {
|
|
cloned := *value
|
|
users[key] = &cloned
|
|
}
|
|
r.Users = users
|
|
|
|
return r
|
|
}
|
|
|
|
type RuleType string
|
|
|
|
type RuleFilter struct {
|
|
ListQueryFilter
|
|
States []enum.RuleState
|
|
Sort enum.RuleSort `json:"sort"`
|
|
Order enum.Order `json:"order"`
|
|
}
|
|
|
|
// Violation represents a single violation.
|
|
type Violation struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
Params []any `json:"params"`
|
|
}
|
|
|
|
// RuleViolations holds several violations of a rule.
|
|
type RuleViolations struct {
|
|
Rule RuleInfo `json:"rule"`
|
|
Bypassable bool `json:"bypassable"`
|
|
Bypassed bool `json:"bypassed"`
|
|
Violations []Violation `json:"violations"`
|
|
}
|
|
|
|
func (violations *RuleViolations) Add(code, message string) {
|
|
violations.Violations = append(violations.Violations, Violation{
|
|
Code: code,
|
|
Message: message,
|
|
Params: nil,
|
|
})
|
|
}
|
|
|
|
func (violations *RuleViolations) Addf(code, format string, params ...any) {
|
|
violations.Violations = append(violations.Violations, Violation{
|
|
Code: code,
|
|
Message: fmt.Sprintf(format, params...),
|
|
Params: params,
|
|
})
|
|
}
|
|
|
|
func (violations *RuleViolations) IsCritical() bool {
|
|
return violations.Rule.State == enum.RuleStateActive && len(violations.Violations) > 0 && !violations.Bypassed
|
|
}
|
|
|
|
func (violations *RuleViolations) IsBypassed() bool {
|
|
return violations.Rule.State == enum.RuleStateActive && len(violations.Violations) > 0 && violations.Bypassed
|
|
}
|
|
|
|
// RuleInfo holds basic info about a rule that is used to describe the rule in RuleViolations.
|
|
type RuleInfo struct {
|
|
SpacePath string `json:"space_path,omitempty"`
|
|
RepoPath string `json:"repo_path,omitempty"`
|
|
|
|
ID int64 `json:"-"`
|
|
Identifier string `json:"identifier"`
|
|
Type RuleType `json:"type"`
|
|
State enum.RuleState `json:"state"`
|
|
}
|
|
|
|
// TODO [CODE-1363]: remove after identifier migration.
|
|
func (r RuleInfo) MarshalJSON() ([]byte, error) {
|
|
// alias allows us to embed the original object while avoiding an infinite loop of marshaling.
|
|
type alias RuleInfo
|
|
return json.Marshal(&struct {
|
|
alias
|
|
UID string `json:"uid"`
|
|
}{
|
|
alias: (alias)(r),
|
|
UID: r.Identifier,
|
|
})
|
|
}
|
|
|
|
type RuleInfoInternal struct {
|
|
RuleInfo
|
|
Pattern json.RawMessage
|
|
Definition json.RawMessage
|
|
}
|
|
|
|
type RulesViolations struct {
|
|
Message string `json:"message"`
|
|
Violations []RuleViolations `json:"violations"`
|
|
}
|
|
|
|
type DryRunRulesOutput struct {
|
|
DryRunRules bool `json:"dry_run_rules,omitempty"`
|
|
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
|
|
}
|