Statistics
| Branch: | Tag: | Revision:

one / include / PoolObjectSQL.h @ 202b47e9

History | View | Annotate | Download (21.8 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#ifndef POOL_OBJECT_SQL_H_
18
#define POOL_OBJECT_SQL_H_
19

    
20
#include "ObjectSQL.h"
21
#include "ObjectXML.h"
22
#include "Template.h"
23

    
24
#include <pthread.h>
25
#include <string.h>
26

    
27
using namespace std;
28

    
29
class PoolObjectAuth;
30

    
31
/**
32
 * PoolObject class. Provides a SQL backend interface for Pool components. Each
33
 * object is identified with and unique OID
34
 *
35
 * Note: The PoolObject provides a synchronization mechanism (mutex). This
36
 * implementation assumes that the mutex IS LOCKED when the class destructor
37
 * is called.
38
 */
39
class PoolObjectSQL : public ObjectSQL, public ObjectXML
40
{
41
public:
42
    /* ---------------------------------------------------------------------- */
43
    /* Class Constructors & Constants                                         */
44
    /* ---------------------------------------------------------------------- */
45

    
46
    /**
47
     *  OpenNebula objects. This definitions are used by other core components
48
     *  like the AuthZ/AuthN module
49
     */
50
    enum ObjectType
51
    {
52
        NONE           = 0x0000000000000000LL,
53
        VM             = 0x0000001000000000LL,
54
        HOST           = 0x0000002000000000LL,
55
        NET            = 0x0000004000000000LL,
56
        IMAGE          = 0x0000008000000000LL,
57
        USER           = 0x0000010000000000LL,
58
        TEMPLATE       = 0x0000020000000000LL,
59
        GROUP          = 0x0000040000000000LL,
60
        ACL            = 0x0000080000000000LL,
61
        DATASTORE      = 0x0000100000000000LL,
62
        CLUSTER        = 0x0000200000000000LL,
63
        DOCUMENT       = 0x0000400000000000LL,
64
        ZONE           = 0x0000800000000000LL,
65
        SECGROUP       = 0x0001000000000000LL,
66
        VDC            = 0x0002000000000000LL,
67
        VROUTER        = 0x0004000000000000LL,
68
        MARKETPLACE    = 0x0008000000000000LL,
69
        MARKETPLACEAPP = 0x0010000000000000LL,
70
        VMGROUP        = 0x0020000000000000LL
71
    };
72

    
73
    static string type_to_str(ObjectType ob)
74
    {
75
        switch (ob)
76
        {
77
            case VM:             return "VM" ; break;
78
            case HOST:           return "HOST" ; break;
79
            case NET:            return "NET" ; break;
80
            case IMAGE:          return "IMAGE" ; break;
81
            case USER:           return "USER" ; break;
82
            case TEMPLATE:       return "TEMPLATE" ; break;
83
            case GROUP:          return "GROUP" ; break;
84
            case ACL:            return "ACL" ; break;
85
            case DATASTORE:      return "DATASTORE" ; break;
86
            case CLUSTER:        return "CLUSTER" ; break;
87
            case DOCUMENT:       return "DOCUMENT" ; break;
88
            case ZONE:           return "ZONE" ; break;
89
            case SECGROUP:       return "SECGROUP" ; break;
90
            case VDC:            return "VDC" ; break;
91
            case VROUTER:        return "VROUTER" ; break;
92
            case MARKETPLACE:    return "MARKETPLACE" ; break;
93
            case MARKETPLACEAPP: return "MARKETPLACEAPP" ; break;
94
            case VMGROUP:        return "VMGROUP" ; break;
95
            default:             return "";
96
        }
97
    };
98

    
99
    /* ---------------------------------------------------------------------- */
100

    
101
    PoolObjectSQL(int            id,
102
                  ObjectType    _obj_type,
103
                  const string& _name,
104
                  int           _uid,
105
                  int           _gid,
106
                  const string& _uname,
107
                  const string& _gname,
108
                  const char *  _table)
109
            :ObjectSQL(),
110
             ObjectXML(),
111
             oid(id),
112
             obj_type(_obj_type),
113
             name(_name),
114
             uid(_uid),
115
             gid(_gid),
116
             uname(_uname),
117
             gname(_gname),
118
             valid(true),
119
             owner_u(1),
120
             owner_m(1),
121
             owner_a(0),
122
             group_u(0),
123
             group_m(0),
124
             group_a(0),
125
             other_u(0),
126
             other_m(0),
127
             other_a(0),
128
             obj_template(0),
129
             locked(false),
130
             lock_owner(""),
131
             lock_expires(0),
132
             table(_table)
133
    {
134
        pthread_mutex_init(&mutex,0);
135
    };
136

    
137
    virtual ~PoolObjectSQL()
138
    {
139
        pthread_mutex_unlock(&mutex);
140

    
141
        pthread_mutex_destroy(&mutex);
142
    };
143

    
144
    /* --------------------------------------------------------------------- */
145

    
146
    int get_oid() const
147
    {
148
        return oid;
149
    };
150

    
151
    ObjectType get_type() const
152
    {
153
        return obj_type;
154
    };
155

    
156
    /**
157
     *  Check if the object name contains invalid characters or exceed the max.
158
     *  length. By Default these are not allowed "&|:\;/'#{}()$
159
     *    @param obj_name for this object
160
     *    @param extra_chars aditional invalid characters to test
161
     *    @param error_str describing the error
162
     *    @return true if the name is valid
163
     */
164
    static bool name_is_valid(const string& obj_name, const string& extra_chars,
165
                              string& error_str);
166

    
167
    /**
168
     *  Check if the object name is valid, no extra characters needed to be
169
     *  tested.
170
     */
171
    static bool name_is_valid(const string& obj_name, string& error_str)
172
    {
173
        return name_is_valid(obj_name, "", error_str);
174
    }
175

    
176
    const string& get_name() const
177
    {
178
        return name;
179
    };
180

    
181
    /**
182
     *  Set the name of the object and check if it is valid.
183
     *    @param _name the new name
184
     *    @param error_str describing the error if any
185
     *
186
     *    @return 0 if the name was changed
187
     */
188
    int set_name(const string& _name, string& error_str)
189
    {
190
        if (!name_is_valid(_name, error_str))
191
        {
192
            return -1;
193
        }
194

    
195
        name = _name;
196

    
197
        return 0;
198
    };
199

    
200
    int get_uid() const
201
    {
202
        return uid;
203
    };
204

    
205
    int get_gid() const
206
    {
207
        return gid;
208
    };
209

    
210
    const string& get_uname() const
211
    {
212
        return uname;
213
    };
214

    
215
    const string& get_gname() const
216
    {
217
        return gname;
218
    };
219

    
220
    /**
221
     * Changes the object's owner
222
     * @param _uid New User ID
223
     * @param _uname Name of the new user
224
     */
225
    void set_user(int _uid, const string& _uname)
226
    {
227
        uid   = _uid;
228
        uname = _uname;
229
    }
230

    
231
    /**
232
     * Changes the object's group id
233
     * @param _gid New Group ID
234
     * @param _gname Name of the new group
235
     */
236
    void set_group(int _gid, const string& _gname)
237
    {
238
        gid   = _gid;
239
        gname = _gname;
240
    };
241

    
242
    /**
243
     * Changes the object's permissions
244
     *
245
     * @param _owner_u New permission: 1 allow, 0 deny, -1 do not change
246
     * @param _owner_m New permission: 1 allow, 0 deny, -1 do not change
247
     * @param _owner_a New permission: 1 allow, 0 deny, -1 do not change
248
     * @param _group_u New permission: 1 allow, 0 deny, -1 do not change
249
     * @param _group_m New permission: 1 allow, 0 deny, -1 do not change
250
     * @param _group_a New permission: 1 allow, 0 deny, -1 do not change
251
     * @param _other_u New permission: 1 allow, 0 deny, -1 do not change
252
     * @param _other_m New permission: 1 allow, 0 deny, -1 do not change
253
     * @param _other_a New permission: 1 allow, 0 deny, -1 do not change
254
     * @param error_str Returns the error reason, if any
255
     *
256
     * @return 0 on success
257
     */
258
    virtual int set_permissions(int _owner_u,
259
                                int _owner_m,
260
                                int _owner_a,
261
                                int _group_u,
262
                                int _group_m,
263
                                int _group_a,
264
                                int _other_u,
265
                                int _other_m,
266
                                int _other_a,
267
                                string& error_str);
268

    
269
    /* --------------------------------------------------------------------- */
270

    
271
    /**
272
     *  Check if the object is valid
273
     *    @return true if object is valid
274
     */
275
    const bool& isValid() const
276
    {
277
       return valid;
278
    };
279

    
280
    /**
281
     *  Set the object valid flag
282
     *  @param _valid new valid flag
283
     */
284
    void set_valid(const bool _valid)
285
    {
286
        valid = _valid;
287
    };
288

    
289
    /**
290
     *  Function to lock the object
291
     */
292
    void lock()
293
    {
294
        pthread_mutex_lock(&mutex);
295
    };
296

    
297
    /**
298
     *  Function to unlock the object
299
     */
300
    void unlock()
301
    {
302
        pthread_mutex_unlock(&mutex);
303
    };
304

    
305
    /**
306
     * Function to print the object into a string in XML format
307
     * base64 encoded
308
     *  @param xml the resulting XML string
309
     *  @return a reference to the generated string
310
     */
311
    virtual string& to_xml64(string &xml64);
312

    
313
    /**
314
     * Function to print the object into a string in XML format
315
     *  @param xml the resulting XML string
316
     *  @return a reference to the generated string
317
     */
318
    virtual string& to_xml(string& xml) const = 0;
319

    
320
    /**
321
     *  Rebuilds the object from an xml formatted string
322
     *    @param xml_str The xml-formatted string
323
     *
324
     *    @return 0 on success, -1 otherwise
325
     */
326
    virtual int from_xml(const string &xml_str) = 0;
327

    
328
    // ------------------------------------------------------------------------
329
    // Template
330
    // ------------------------------------------------------------------------
331
    /**
332
     *  Gets the first VectorAttribute of the specified type with the given name.
333
     *  Const and non-const versions of this method is provided
334
     *    @param name the attribute name.
335
     *    @return true first attribute or 0 if not found or wrong type
336
     */
337
    const VectorAttribute * get_template_attribute(const string& s) const
338
    {
339
        return obj_template->get(s);
340
    }
341

    
342
    VectorAttribute * get_template_attribute(const string& s)
343
    {
344
        return obj_template->get(s);
345
    }
346

    
347
    /**
348
     *  Gets the values of a template attribute, as a list of VectorAttributes
349
     *    @param name of the attribute
350
     *    @param values of the attribute
351
     *    @return the number of values
352
     */
353
        template<typename T>
354
    int get_template_attribute(const char * name, vector<const T*>& values) const
355
    {
356
        return obj_template->get(name,values);
357
    };
358

    
359
        template<typename T>
360
    int get_template_attribute(const char * name, vector<T*>& values) const
361
    {
362
        return obj_template->get(name,values);
363
    };
364

    
365
    /**
366
     *  These methods gets the value of a SingleAttribute and converts it to the
367
         *  target type
368
     *    @param name of the attribute
369
     *    @param value of the attribute, will be ""/0/false if not defined or
370
     *    not a single attribute
371
         *
372
     *    @return true if the attribute was found and is a valid type for the
373
         *    target value
374
     */
375
        template<typename T>
376
    bool get_template_attribute(const char * name, T& value) const
377
    {
378
        return obj_template->get(name,value);
379
    }
380

    
381
    /**
382
     *  These methods get and remove a string based attribute (single)
383
     *    @param name of the attribute
384
     *    @param value of the attribute (a string), will be ""/0/false if not
385
         *    defined or  not a single attribute, depending on the target value type
386
     *    @return the number of attributes erased
387
     */
388
        template<typename T>
389
    int erase_template_attribute(const char * name, T& value)
390
    {
391
        obj_template->get(name,value);
392
        return obj_template->erase(name);
393
    }
394

    
395
    /**
396
     *  Adds a new attribute to the template (replacing it if
397
     *  already defined), the object's mutex SHOULD be locked
398
     *    @param name of the new attribute
399
     *    @param value of the new attribute
400
     *    @return 0 on success
401
     */
402
        template<typename T>
403
    int replace_template_attribute(const string& name, const T& value)
404
    {
405
        return obj_template->replace(name, value);
406
    }
407

    
408
    /**
409
     *  Removes an attribute from the template. The attributes are returned, and
410
     *  MUST be freed by the calling funtion
411
     *    @param name of the attribute
412
     *    @param values a vector containing a pointer to the attributes
413
     *    @return the number of attributes removed
414
     */
415
        template<typename T>
416
    int remove_template_attribute(const string& n, vector<T *>& v)
417
    {
418
        return obj_template->remove(n, v);
419
    }
420

    
421
    /**
422
     *  Generates a XML string for the template of the Object
423
     *    @param xml the string to store the XML description.
424
     */
425
    string& template_to_xml(string &xml) const
426
    {
427
        return obj_template->to_xml(xml);
428
    }
429

    
430
    /**
431
     *  Removes an attribute
432
     *    @param name of the attribute
433
     */
434
    int remove_template_attribute(const string& name)
435
    {
436
        return obj_template->erase(name);
437
    }
438

    
439
    /**
440
     *  Sets an error message with timestamp in the template
441
     *    @param message Message string
442
     */
443
    virtual void set_template_error_message(const string& message);
444

    
445
    /**
446
     *  Deletes the error message from the template
447
     */
448
    virtual void clear_template_error_message();
449

    
450
    /**
451
     *  Adds a string attribute
452
     *    @param att_name Name for the attribute
453
     *    @param att_val Message string
454
     */
455
        template<typename T>
456
    void add_template_attribute(const string& name, const T& value)
457
    {
458
        obj_template->add(name, value);
459
    }
460

    
461
    template<typename T>
462
    void add_template_attribute(vector<T *>& values)
463
    {
464
        obj_template->set(values);
465
    }
466

    
467
    /**
468
     *  Factory method for templates, it should be implemented
469
     *  by classes that uses templates
470
     *    @return a new template
471
     */
472
    virtual Template * get_new_template() const
473
    {
474
        return 0;
475
    }
476

    
477
    /**
478
     *  Replace template for this object. Object should be updated
479
     *  after calling this method
480
     *    @param tmpl_str new contents
481
     *    @param keep_restricted If true, the restricted attributes of the
482
     *    current template will override the new template
483
     *    @param error string describing the error if any
484
     *    @return 0 on success
485
     */
486
    virtual int replace_template(const string& tmpl_str, bool keep_restricted, string& error);
487

    
488
    /**
489
     *  Append new attributes to this object's template. Object should be updated
490
     *  after calling this method
491
     *    @param tmpl_str new contents
492
     *    @param keep_restricted If true, the restricted attributes of the
493
     *    current template will override the new template
494
     *    @param error string describing the error if any
495
     *    @return 0 on success
496
     */
497
    virtual int append_template(const string& tmpl_str, bool keep_restricted, string& error);
498

    
499
    /**
500
     *  Fills a auth class to perform an authZ/authN request based on the object
501
     *  attributes
502
     *    @param auths to be filled
503
     */
504
    virtual void get_permissions(PoolObjectAuth& auths);
505

    
506
    /**
507
     * Tries to get the DB lock. This is a mutex requested by external
508
     * applications, not related to the internal mutex lock. The object
509
     * must be locked (internal memory mutex) before this method is called
510
     *
511
     * @param owner String to identify who requested the lock
512
     *
513
     * @return 0 if the lock was granted, -1 if the object is already locked
514
     */
515
    int lock_db(const string& owner);
516

    
517
    /**
518
     * Unlocks the DB lock for external applications. The object must be locked
519
     * (internal memory mutex) before this method is called
520
     *
521
     * @param owner String to identify who requested the lock
522
     */
523
    void unlock_db(const string& owner);
524

    
525
protected:
526

    
527
    /**
528
     *  Callback function to unmarshall a PoolObjectSQL
529
     *    @param num the number of columns read from the DB
530
     *    @param names the column names
531
     *    @param vaues the column values
532
     *    @return 0 on success
533
     */
534
    int select_cb(void *nil, int num, char **values, char **names)
535
    {
536
        if ( (!values[0]) || (num != 1) )
537
        {
538
            return -1;
539
        }
540

    
541
        return from_xml(values[0]);
542
    };
543

    
544
    /**
545
     *  Reads the PoolObjectSQL (identified by its OID) from the database.
546
     *    @param db pointer to the db
547
     *    @return 0 on success
548
     */
549
    virtual int select(SqlDB *db);
550

    
551
    /**
552
     *  Reads the PoolObjectSQL (identified by its OID) from the database.
553
     *    @param db pointer to the db
554
     *    @return 0 on success
555
     */
556
    virtual int select(SqlDB *db, const string& _name, int _uid);
557

    
558
    /**
559
     *  Drops object from the database
560
     *    @param db pointer to the db
561
     *    @return 0 on success
562
     */
563
    virtual int drop(SqlDB *db);
564

    
565
    /**
566
     *  Function to output a pool object into a stream in XML format
567
     *    @param oss the output stream
568
     *    @param num the number of columns read from the DB
569
     *    @param names the column names
570
     *    @param vaues the column values
571
     *    @return 0 on success
572
     */
573
    static int dump(ostringstream& oss, int num, char **values, char **names)
574
    {
575
        if ( (!values[0]) || (num != 1) )
576
        {
577
            return -1;
578
        }
579

    
580
        oss << values[0];
581
        return 0;
582
    };
583

    
584
    /**
585
     * Prints the permissions into a string in XML format
586
     *  @param xml the resulting XML string
587
     *  @return a reference to the generated string
588
     */
589
    string& perms_to_xml(string& xml) const;
590

    
591
    /**
592
     *  Rebuilds the object permissions from the xml. ObjectXML::update_from_str
593
     *  must be called before this method
594
     *
595
     *    @return 0 on success, -1 otherwise
596
     */
597
    int perms_from_xml();
598

    
599
    /**
600
     * Sets the permission attribute to the new_perm value, if it is different
601
     * from -1
602
     *
603
     *   @param perm the permissions attribute, must be -1, 0 or 1, its value
604
     *   must be checked before
605
     *   @param new_perm the new value. If it is -1, it will be ignored
606
     */
607
    void set_perm(int &perm, const int &new_perm)
608
    {
609
        if ( new_perm != -1 )
610
        {
611
            perm = new_perm;
612
        }
613
    };
614

    
615
    /**
616
     * Initializes the object's permissions, according to the provided umask.
617
     *
618
     * @param umask Permission mask, similar to unix umask.
619
     * For example a umask of 137 will set the permissions "um- u-- ---"
620
     */
621
    void set_umask(int umask);
622

    
623
    /**
624
     *  Sets an error message with timestamp in the template
625
     *    @param name of the error attribute
626
     *    @param message Message string
627
     */
628
    virtual void set_template_error_message(const string& name, const string& message);
629

    
630
    /**
631
     * Child classes can process the new template set with replace_template or
632
     * append_template with this method
633
     *    @param error string describing the error if any
634
     *    @return 0 on success
635
     */
636
    virtual int post_update_template(string& error)
637
    {
638
        return 0;
639
    };
640

    
641
    /**
642
     * Prints the lock info into a string in XML format
643
     *  @param xml the resulting XML string
644
     *  @return a reference to the generated string
645
     */
646
    string& lock_db_to_xml(string& xml) const;
647

    
648
    /**
649
     *  Rebuilds the lock info from the xml. ObjectXML::update_from_str
650
     *  must be called before this method
651
     *
652
     *    @return 0 on success, -1 otherwise
653
     */
654
    int lock_db_from_xml();
655

    
656
    /**
657
     *  The object's unique ID
658
     */
659
    int     oid;
660

    
661
    /**
662
     *  The object type
663
     */
664
    ObjectType obj_type;
665

    
666
    /**
667
     *  The object's name
668
     */
669
    string  name;
670

    
671
    /**
672
     *  Object's owner, set it to -1 if owner is not used
673
     */
674
    int     uid;
675

    
676
    /**
677
     *  Object's group, set it to -1 if group is not used
678
     */
679
    int     gid;
680

    
681
    /**
682
     *  Name of the object's owner, empty if owner is not used
683
     */
684
    string  uname;
685

    
686
    /**
687
     *  Name of the object's group,, empty if group is not used
688
     */
689
    string  gname;
690

    
691
    /**
692
     *  The contents of this object are valid
693
     */
694
    bool    valid;
695

    
696
    /**
697
     *  Permissions for the owner user
698
     */
699
    int     owner_u;
700
    int     owner_m;
701
    int     owner_a;
702

    
703
    /**
704
     *  Permissions for users in the object's group
705
     */
706
    int     group_u;
707
    int     group_m;
708
    int     group_a;
709

    
710
    /**
711
     *  Permissions for the rest
712
     */
713
    int     other_u;
714
    int     other_m;
715
    int     other_a;
716

    
717
    /**
718
     *  Template for this object, will be allocated if needed
719
     */
720
    Template * obj_template;
721

    
722
    /**
723
     *  Flag for the DB lock
724
     */
725
    bool    locked;
726

    
727
    /**
728
     *  Owner of the DB lock
729
     */
730
    string  lock_owner;
731

    
732
    /**
733
     *  Expiration time for the DB lock
734
     */
735
    time_t  lock_expires;
736

    
737
private:
738
    /**
739
     *  Characters that can not be in a name
740
     */
741
    static const string INVALID_NAME_CHARS;
742

    
743
    /**
744
     * Expiration time for the lock stored in the DB
745
     */
746
    static const int LOCK_DB_EXPIRATION;
747

    
748
    /**
749
     *  The PoolSQL, friend to easily manipulate its Objects
750
     */
751
    friend class PoolSQL;
752

    
753
    /**
754
     * The mutex for the PoolObject. This implementation assumes that the mutex
755
     * IS LOCKED when the class destructor is called.
756
     */
757
    pthread_mutex_t mutex;
758

    
759
    /**
760
     *  Pointer to the SQL table for the PoolObjectSQL
761
     */
762
    const char * table;
763
};
764

    
765
#endif /*POOL_OBJECT_SQL_H_*/