@@ -2,41 +2,57 @@ package ranger
22
33import (
44 "context"
5+ "errors"
56 "log"
67 "strings"
78 "time"
89
10+ "gopkg.in/yaml.v3"
11+
912 "github.com/patterninc/heimdall/pkg/sql/parser"
13+ "github.com/patterninc/heimdall/pkg/sql/parser/factory"
14+ )
15+
16+ var (
17+ ErrRangerClientConfigIsRequired = errors .New ("ranger client_config is required" )
18+ ErrRangerParserConfigIsRequired = errors .New ("ranger parser_config is required" )
19+ ErrRangerParserTypeIsRequired = errors .New ("ranger parser_config.type is required" )
20+ ErrRangerParserDefaultCatalogIsRequired = errors .New ("ranger parser_config.default_catalog is required" )
21+ ErrRangerUnsupportedParserType = errors .New ("unsupported ranger parser_config.type. supported types: trino" )
1022)
1123
12- // only private
13- // add links
1424type Ranger struct {
15- Name string `yaml:"name,omitempty" json:"name,omitempty"`
16- ServiceName string `yaml:"service_name,omitempty" json:"service_name,omitempty"`
17- Client * ClientWrapper `yaml:"client,omitempty" json:"client,omitempty"`
25+ Name string `yaml:"name,omitempty" json:"name,omitempty"`
26+ ServiceName string `yaml:"service_name,omitempty" json:"service_name,omitempty"`
27+ Client Client
1828 SyncIntervalInMinutes int `yaml:"sync_interval_in_minutes,omitempty" json:"sync_interval_in_minutes,omitempty"`
1929 AccessReceiver parser.AccessReceiver `yaml:"parser,omitempty" json:"parser,omitempty"`
20- permissionsByUser map [string ]* UserPermissions
30+ permissionsByUser map [string ]* userPermissions
2131}
2232
23- type ParserConfig struct {
33+ type parserConfig struct {
2434 Type string `yaml:"type,omitempty" json:"type,omitempty"`
2535 DefaultCatalog string `yaml:"default_catalog,omitempty" json:"default_catalog,omitempty"`
2636}
2737
28- type UserPermissions struct {
29- AllowPolicies map [parser.Action ][]* Policy // todo AllowPolicies
38+ type clientConfig struct {
39+ Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
40+ Username string `yaml:"username,omitempty" json:"username,omitempty"`
41+ Password string `yaml:"password,omitempty" json:"password,omitempty"`
42+ }
43+
44+ type userPermissions struct {
45+ AllowPolicies map [parser.Action ][]* Policy
3046 DenyPolicies map [parser.Action ][]* Policy
3147}
3248
33- func (r * Ranger ) Init (ctx context. Context ) error {
49+ func (r * Ranger ) Init () error {
3450 // first time lets sync state explicitly
3551 if err := r .SyncState (); err != nil {
3652 return err
3753 }
3854 go func () {
39- ctx , cancel := context .WithCancel (ctx )
55+ ctx , cancel := context .WithCancel (context . Background () )
4056 defer cancel ()
4157
4258 ticker := time .NewTicker (time .Duration (r .SyncIntervalInMinutes ) * time .Minute )
@@ -115,7 +131,7 @@ func (r *Ranger) SyncState() error {
115131 }
116132 }
117133
118- newPermissionsByUser := map [string ]* UserPermissions {}
134+ newPermissionsByUser := map [string ]* userPermissions {}
119135 for _ , policy := range policies {
120136 if ! policy .IsEnabled {
121137 continue
@@ -133,7 +149,7 @@ func (r *Ranger) SyncState() error {
133149 controlledActions := policy .getControlledActions (usersByGroup )
134150 for userName , actions := range controlledActions .allowedActionsByUser {
135151 if _ , ok := newPermissionsByUser [userName ]; ! ok {
136- newPermissionsByUser [userName ] = & UserPermissions {
152+ newPermissionsByUser [userName ] = & userPermissions {
137153 AllowPolicies : map [parser.Action ][]* Policy {},
138154 DenyPolicies : map [parser.Action ][]* Policy {},
139155 }
@@ -144,7 +160,7 @@ func (r *Ranger) SyncState() error {
144160 }
145161 for userName , actions := range controlledActions .deniedActionsByUser {
146162 if _ , ok := newPermissionsByUser [userName ]; ! ok {
147- newPermissionsByUser [userName ] = & UserPermissions {
163+ newPermissionsByUser [userName ] = & userPermissions {
148164 AllowPolicies : map [parser.Action ][]* Policy {},
149165 DenyPolicies : map [parser.Action ][]* Policy {},
150166 }
@@ -159,3 +175,47 @@ func (r *Ranger) SyncState() error {
159175 log .Println ("Syncing users and groups from Apache Ranger for service:" , r .ServiceName )
160176 return nil
161177}
178+
179+ func (r * Ranger ) UnmarshalYAML (value * yaml.Node ) error {
180+ type rawRanger struct {
181+ Name string `yaml:"name,omitempty" json:"name,omitempty"`
182+ ServiceName string `yaml:"service_name,omitempty" json:"service_name,omitempty"`
183+ SyncIntervalInMinutes int `yaml:"sync_interval_in_minutes,omitempty" json:"sync_interval_in_minutes,omitempty"`
184+ Client * clientConfig `yaml:"client"`
185+ Parser * parserConfig `yaml:"parser"`
186+ }
187+
188+ var raw rawRanger
189+ if err := value .Decode (& raw ); err != nil {
190+ return err
191+ }
192+
193+ if raw .Client == nil {
194+ return ErrRangerClientConfigIsRequired
195+ }
196+ if raw .Parser == nil {
197+ return ErrRangerParserConfigIsRequired
198+ }
199+ if raw .Parser .Type == "" {
200+ return ErrRangerParserTypeIsRequired
201+ }
202+ if raw .Parser .DefaultCatalog == "" {
203+ return ErrRangerParserDefaultCatalogIsRequired
204+ }
205+
206+ r .Name = raw .Name
207+ r .ServiceName = raw .ServiceName
208+ r .SyncIntervalInMinutes = raw .SyncIntervalInMinutes
209+ r .Client = NewClient (raw .Client .Endpoint , raw .Client .Username , raw .Client .Password )
210+
211+ accessReceiver , err := factory .CreateParserByType (raw .Parser .Type , raw .Parser .DefaultCatalog )
212+ if err != nil {
213+ return ErrRangerUnsupportedParserType
214+ }
215+
216+ r .AccessReceiver = accessReceiver
217+ if r .SyncIntervalInMinutes == 0 {
218+ r .SyncIntervalInMinutes = 5
219+ }
220+ return nil
221+ }
0 commit comments