學習saltstack (一)


salt介紹

Salt是一個基礎平台管理工具

Salt是一個配置管理系統,能夠維護預定義狀態的遠程節點

Salt是一個分布式遠程執行系統,用來在遠程節點上執行命令和查詢數據

salt的核心功能

是命令發送到遠程系統,而且是並行發送不是串行的

使用安全加密協議

對網絡要求比較低,使用最小最快的網絡載荷

提供簡單的編程接口(salt使用python開發)

salt的優點

saltstack使用python語言編寫,相當輕量級。 http://www.python.org

saltstack通訊層采用ZeroMQ PUB-SUB pattern實現,使得它很快速。http://www.zearmq.org

saltstack是開源的,通過python可以自己編寫模塊。

salt端口說明

salt-master啟動時會啟動兩個端口

4505:為salt的消息發布專用端口 
4506:位客戶端與服務端通信的端口。  ---監控此端口可以監控哪些minion收到的消息,並回復了結果。

實驗圖解

安裝saltstack

1、安裝指定epel源
    baseurl=http://repo.saltstack.com/yum/redhat/6.7/x86_64/
2、安裝master
    yum -y install salt-master
3、安裝minion
    yum -y install salt-minion

配置saltstack

1、修改minion配置文件
    vim /etc/salt/master 
    #master: salt         默認master配置的為salt,需在/etc/hosts中增加映射,也可以修改為master的IP地址或域名
    #id:              指定minion的標識, id要是唯一的,默認為主機名
    vim /etc/hosts
    192.168.4.16 salt        master端ip       
2、修改master配置文件
    vim /etc/salt/master        
    log_level: debug      調試過程日志級別修改為debug級別,生產系統可根據實際情況配置
3、啟動服務
    /etc/init.d/salt-master start    先啟動master端     
    /etc/init.d/salt-minion start
  ping salt 測試與master主機是否連通 備注:master端修改配置文件不用重啟,默認直接生效

服務端master命令

salt-key        
            -a          #添加指定id
            -A          #添加全部
            -r          #拒絕指定id
            -R          #拒絕全部
            -d          #刪除指定id
            -D          #刪除全部
            -y          #去除每步操作確認的一步。
       -L      #列出所有的minion端的key
       -l      #列出特定minion端發過來的請求
提示:無論是accept還是delete都支持Linux的shell通配符。

SaltStack認證

            1、minion在第一次啟動時,會在/etc/salt/pki/minion/下自動生成minion.pem(private key)和minion.pub(public key),然后將minion.pub發送給master。
            2、master在第一次啟動時,會在/etc/salt/pki/master下自動生成master.pem。在接收到minion的public key后,
         通過salt-key命令accept minion public key,這樣在master的/etc/salt/pki/master/minions下的將會存放以minion id命名的public key,
         客戶端會保存一份master的public key,在/etc/salt/pki/minion_master.pub 3、通過兩個步驟的驗證,master就能對minion發送指令了。

實驗一:修改主機名

1、minion端:
hostname salt-client-01
sed -i 's#HOSTNAME=*#HOSTNAME=salt-client-01#g' /etc/sysconfig/network
rm -rf /etc/salt/minion_id   /etc/salt/pki/*   
/etc/init.d/salt-minion   restart
2、master端:
salt-key  -d  salt-client01 -y
salt-key  -L
salt-key  -A -y
salt '*' test.ping    
3、如果再master不刪除minion的key,有可能minion程序啟動后,會自動殺死自己。原因是:minion啟動后,會生成自己的key(主機名、IP地址和一些其它信息聯合生成的),
  當向master注冊后,會保存一個master的key。當主機名修改后自己的key會改變,如果master不刪除之前minion的key,不僅會注冊失敗,minion還會殺死自己的進程;
4、minion的主機名會緩存到/etc/salt/minion_id文件里面,修改主機名后需要刪除這個文件;

實驗二:遷移master主機

思路(原理):
1、對minion而言只認master服務器上的的key與minion自己保存的master的key是否有沖突,沒有沖突就不會有問題
2、minion要執向新的master的地址
操作步驟:
第一步:將masterold上的所有key文件打包上傳到masternew服務器上,解壓,然后重啟master
    tar -zcvf pki.tar.gz /etc/salt/pki/
    scp pki.tar.gz 192.168.4.18:/etc/salt/pki/
    cd /etc/salt/;tar -xf  pki.tar.gz
    /etc/init.d/salt-master restart
    salt-key -L
第二步:修改所有minion配置文件,將master執向新的地址
    salt '*' cmd.run "sed -i 's/16/18/g' /etc/hosts"
第三步:驗證是否修改成功
    salt '*' cmd.run 'grep salt /etc/hosts'
第四步:重啟所有minion服務
     salt '*' service.restart salt-minion
第五步:在masternew上驗證是否接管了所有minion
    salt '*' test.ping

returnner (日志輸出)

默認情況下,發送給salt minion的命令執行結果將返回給salt master,Saltstack Returner的接口允許將結果發送給任意系統。
可做minion的監控使用
 
        

內置的returnner模塊列表

        carbon_return       將結果返回給carbon接收器
            cassandea_return    將結果返回給Cassandra ColumnFamily
            local               將結果返回給本地的測試returner接口,即打印當前的結果
            mongo_future_return 將結果返回給mongodb
            mongo_return        將結果返回給mongodb
            mysql               將結果返回給MySQL
            postgres            將結果返回給postgres
            redis_return        將結果返回給redis
            sentry_return       將結果返回給sentry
            smtp_return         通過email返回salt數據
            syslog_return       將結果返回給操作系統的syslog facility

實驗三:returnner返回到syslog

1、在salt-master執行命令:
    salt '*' test.ping --return syslog
2、在salt-minion查看syslog日志
    tail -f /var/log/messages
這個log會放在每一個minion中的  /var/log/messages  中 ,根本不是我們想要的結果

實驗四:returnner返回給mysql(單邊模式)

 

 

1、安裝mysql(可以在master也可以在其它服務器)
    yum install –y mysql mysql-server
2、啟動mysql並設置root密碼
    service mysqld start
    mysqladmin -u root password '123456'
3、創建數據庫,並授權
--創建數據庫
CREATE DATABASE `salt`DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; 
USE `salt`; 

DROP TABLE IF EXISTS `jids`; 
CREATE TABLE `jids` 
(`jid` varchar(255) NOT NULL,`load` mediumtext NOT NULL,UNIQUE KEY `jid` (`jid`) ) 
ENGINE=InnoDB DEFAULT CHARSET=utf8; 

DROP TABLE IF EXISTS `salt_returns`; 
CREATE TABLE `salt_returns` 
(`fun` varchar(50) NOT NULL,`jid` varchar(255) NOT NULL,`return` mediumtext NOT NULL,`id` varchar(255) NOT NULL,`success` varchar(10) NOT NULL,`full_ret` mediumtext NOT NULL,KEY `id` (`id`),KEY `jid` (`jid`),KEY `fun` (`fun`) ) 
ENGINE=InnoDB DEFAULT CHARSET=utf8;

--授權
GRANT ALL PRIVILEGES ON salt.* to 'salt'@'%' identified by 'salt';
flush privileges;
4、修改所有minion配置文件,在配置文件結尾添加:
     cat /etc/salt/minion
    mysql.host: '192.168.4.16' 
    mysql.user: 'salt' 
    mysql.pass: 'salt' 
    mysql.db: 'salt' 
    mysql.port: 3306
5、重啟所有minion服務
    salt '*' service.restart salt-minion
6、所有minion安裝MySQL-python模塊
     salt '*' cmd.run 'yum install -y MySQL-python'
7、測試寫入mysql
     salt '*' cmd.run 'hostname' --return mysql
8、查看結果 
    mysql> select * from salt_returns;   

event介紹

event是一個本地的ZeroMQ PUB Interace,event是一個開放的系統,用於發送消息通知salt或其它操作系統。
每個event都有一個標簽。時間標簽允許快速至頂過濾事件。除了標簽之外,每個時間都有一個數據結構。這個數據結構是一個dict類型,其中包含關於事件的信息。
salt-master發送命令到salt-minion,minion將命令結果發送給event,master從event讀取返回結果,然后將結果寫入mysql。

系統結構圖

實驗五:讀取event接口,並寫入到mysql

event接口測試:
1、在salt-master  /server/scripts  下新建test.py
    cat test.py
import salt.utils.event
event = salt.utils.event.MasterEvent('/var/run/salt/master')
for data in event.iter_events(full=True):
    print(data)
    print '------'
2、執行這個測試腳本
    python salt-event.py
3、然后再開一個新的master終端進行salt操作:
    salt '*' cmd.run 'hostname'
event-to-mysql測試
1、安裝MySQL軟件,創建數據庫,並授權,在master安裝MySQL-python模塊
2、在master配置文件結尾添加如下配置:
    vi /etc/salt/master
mysql.host: '192.168.4.18' 
mysql.user: 'salt' 
mysql.pass: 'salt' 
mysql.db: 'salt' 
mysql.port: 3306
3、編寫自定義returnn腳本
    vim salt_event_to_mysql.py
#!/bin/env python
#coding=utf8
# Import python libs
import json
# Import salt modules
import salt.config
import salt.utils.event
# Import third part libs
import MySQLdb
__opts__ = salt.config.client_config('/etc/salt/master')
#create MySQL connect
#conn = MySQLdb.connect(host=__opts__['mysql.host'],user=__opts__['mysql.user'],passwd=__opts__['mysql.pass'],db=__opts__['mysql.db'],port=__opts__['mysql.port'])

conn = MySQLdb.connect(host='192.168.3.87',user='salt',passwd='salt',db='salt',port=3306)
cursor = conn.cursor()
# Listen Salt Master Event System
event = salt.utils.event.MasterEvent(__opts__['sock_dir'])
for eachevent in event.iter_events(full=True):
    ret = eachevent['data']
    if "salt/job/" in eachevent['tag']:
        #Return Event
        if ret.has_key('id') and ret.has_key('return'):
            #Ignore saltutil.find_job event
            if ret['fun'] == "saltutil.find_job":
                continue
            sql = '''INSERT INTO `salt_returns`
                (`fun`,`jid`,`return`,`id`,`success`,`full_ret` )
                VALUES (%s,%s,%s,%s,%s,%s)'''
            cursor.execute(sql,(ret['fun'],ret['jid'],
                                json.dumps(ret['return']),ret['id'],
                                ret.get('success', False),json.dumps(ret)))
            cursor.execute("COMMIT")
    # Other Event
    else:
        pass
注意:
MySQLdb.connect(host=__opts__['mysql.host'],user=__opts__['mysql.user'],passwd=__opts__['mysql.pass'],db=__opts__['mysql.db'],
port=__opts__['mysql.port']),要換成自己的實際數據庫地址、數據庫用戶、密碼,如: conn = MySQLdb.connect(host='10.80.0.162',user='salt',passwd='salt',db='salt',port=3306) python語言是根據縮進來識別語法的,上面腳本不要隨意修改縮進,否則可能會出現各種各樣的問題。 4、在master的后台執行自定義return腳本   python salt_event_to_mysql.py & 注意:常見報錯處理“_mysql_exceptions.OperationalError: (1045, "Access denied for user 'salt'@'saltmaster' (using password: YES)")” #使用mysql-client登錄mysql測試 #28000一般為mysql存在空用戶導致,需要先刪除空用戶 5、開一個新的master終端進行測試   salt '*' test.ping 6、在mysql上看是否已經將數據寫入數據庫   select * from salt.salt_returns;
官方例子:
https://github.com/saltstack/salt/tree/develop/salt/returners
https://docs.saltstack.com/en/latest/ref/returners/all/salt.returners.mysql.html

分組

  • 當服務器非常多的時候,就需要分組,分組的方法如下,常用分組已標記為紅色。
letter 含義 例子
G Grains glob匹配 G@os:Centos
E PCRE正則匹配minion_id E@web\d+\.(dev|qa|prod)\.loc
P PCRE正則匹配Grains P@os:(RedHat|Centos)
L minion_id列表 L@vas01,vas02,vas03
I pillar glob匹配 I@pdata:foobar
S 子網/ip地址匹配 S@192.168.1.0/24 or S@192.168.1.100
R Range cluster匹配 R@%foo.bar
D minion data匹配,需要定義data D@key:value
N 組+組匹配 N@group1 or N@group2

  

1、修改master配置文件
    vim /etc/salt/master 
nodegroups:
 test: 'salt0*'
2、測試結果
 salt -N test   test.ping

分組配置可以在單獨的配置文件配置
分組配置語法遵循YAML語言規范

yaml語法三大規則

規則一:縮進

  yaml使用一個固定的縮進風格表示數據層結構關系,Saltstack需要每個縮進級別由兩個空格組成。一定不能使用tab鍵

規則二:冒號

  yaml:
  mykey: my_value
  每個冒號后面一定要有一個空格(以冒號結尾不需要空格,表示文件路徑的模版可以不需要空格)

規則三:短橫線

 想要表示列表項,使用一個短橫杠加一個空格。多個項使用同樣的縮進級別作為同一個列表的一部分

my_dictionary:

- list_value_one

- list_value_two

- list_value_three
  • 縮進:YAML使用一個固定的縮進風格表示數據層結構關系。Salt需要每個縮進級別由兩個空格組成。不要使用tab。
  • 字典:Python的字典是簡單的簡直對。字典的keys在YAML中表現形式是以冒號結尾的字符串。values的表現形式是冒號下面的每一行,用一個空格隔開。
  • 列表:想要表示列表項,使用一個短橫杠加一個控制。多個項使用相同的縮進級別作為同一列表的一部分。

官方網址:http://docs.saltstack.cn/topics/yaml/index.html

模塊介紹

1、salt查看幫助文檔:
    salt 'salt01' sys.doc
2、salt查看有哪些模塊
    salt 'salt01'  sys.list_modules
3、由於模塊太多了,關於salt的模塊可以參考官網:
https://docs.saltstack.com/en/latest/ref/modules/all/
http://blog.csdn.net/chengxuyuanyonghu/article/details/64519496

文件系統

1、修改配置文件
    vim /etc/salt/master
file_roots:        默認格式
  base:            基礎版
    - /srv/salt    腳本目錄
base:基礎版  ---默認使用這個版本
dev:開發版
prod:產品版
2、創建目錄並測試腳本
    mkdir /srv/salt/etc/script
    cat test.sh 
#!/bin/sh
while true
do 
    sleep 1
    echo 1 >> /tmp/1.log
done
執行腳本
 salt 'salt02' cmd.script salt://etc/script/test.sh
注意:由於這個腳本會一直執行,master在執行這個腳本的時候命令不會退出,需要ctrl+c退出。minion端會生成一個tmp***.sh的腳本,minion實際運行的是這個腳本。所以master退出后不影響minion的運行。

創建sls文件

1、創建top.sls
    cat top.sls 
base:                                            #與base,prod,dev 對應
  'salt02':                                      #同步的minion_id
    - test                                       #調用的sls文件名
2、創建test.sls
    cat test.sls 
syncfile:                                               #名稱,可以自定義。如果不寫name的話,這里需寫成目標地址
  file.managed:                                         #file模塊的managed方法
    - source: salt://etc/file/passwd                    #原文件路徑
    - user: root                                        #源文件屬主
    - group: root                                       #源文件屬組
    - mode: 600                                         #源文件權限
    - name: /tmp/passwd                                 #同步目標地址
3、測試
salt 'salt02' state.highstate                 執行top.sls
salt 'salt02' state.sls test                  根目錄
salt 'salt02' state.sls sls.test              相對路徑
salt 'salt02' state.sls sls                   默認init.sls
4、將所有的sls文件放到一個目錄

# tree
.
├── etc
│ ├── file
│ │ └── passwd
│ └── script
│ └── test.sh
├── sls
│ └── test.sls
├── test.sls
└── top.sls

5、默認執行init.sls,程序會自動補充文件后綴(.sls)

# cat init.sls 
hostname:
  cmd.run

# tree
.
├── etc
│ ├── file
│ │ └── passwd
│ └── script
│ └── test.sh
├── sls
│ ├── init.sls
│ └── test.sls
├── test.sls
└── top.sls

# salt 'salt02' state.sls sls

grains

grains主要負責采集客戶端的一些基本信息,這個也可以完全自定義。可以在客戶端自定義,然后自動匯報上來;也可以從服務端定義,然后推下去,采集完后,再匯報上來;pillar根grains比較的話它更靈活。

grains的使用:

1、查看
     salt 'salt01' grains.ls                           查看minion所有的grains的名稱
    salt 'salt01' grains.items                         列出所有grains名稱和對應的值
     salt 'vas01' grains.item os                       列出指定的grains的名稱和值
2、匹配
    salt -G 'uuid:421fa146-86f4-47c1-adc9-0e21d5bad8c8' test.ping
3、自定義grains,在minion端修改配置文件,在文件結尾增加如下配置:
    vim /etc/salt/minion
grains:
  roles:
    - webserver
    - memcache
  deployment: datacenter
  cabinet: 13
4、重啟minion
    /etc/init.d/salt-minion restart
5、查看自定義的grains是否生效
    salt 'study02' grains.items

STATES

salt狀態系統的核心是sls,或者叫**S** aLState文件,SLS表示系統將會是什么樣的一種狀態,而且是以一種簡單的格式來包含這些數據。這些也被叫做配置管理。

SLS文件實際上只是一些:詞典(dictionaries),列表(lists),字符串和數字。

官方網址:https://docs.saltstack.com/en/latest/ref/states/all/

批量安裝nginx服務

1、編寫sls文件
    cat /srv/salt/nginx/init.sls
        nginx:                                    #定義top.sls定義的模塊
          pkg:                                    #使用pkg模塊
            - installed                           #安裝nginx軟件
          service:                                #服務控制模塊
            - running                             #運行狀態
            - enable: True                        #權限開啟
            - reload: True                        #允許reload重啟
            - watch:                              #控制文件
              - pkg: nginx                        #控制的軟件
              - file: /etc/nginx/nginx.conf              #要控制文件的文件定義名稱
              - file: /etc/nginx/conf.d/default.conf      #要控制文件的文件定義名稱
        /etc/nginx/nginx.conf:                   #定義控制文件的名稱
          file.managed:                         #格式語句
            - source: salt://etc/nginx/nginx.conf       #具體的文件目錄
            - user: root                                #執行的用戶
            - group: root                               #執行的用戶組
            - mode: 644                                 #文件權限
        /etc/nginx/conf.d/default.conf:            #定義控制文件的名稱
          file.managed:                            #格式語句
            - source: salt://etc/nginx/conf.d/default.conf #具體的文件目錄
            - user: root                      #執行的用戶
            - group: root                     #執行的用戶組
            - mode: 644                       #文件權限
2、復制配置文件到腳本目錄 cp /etc/nginx/nginx.conf /srv/salt/etc/nginx/ cp /etc/nginx/conf.d/default.conf /srv/salt/etc/nginx/conf.d 3、使用salt批量安裝和並同步配置文件 salt 'salt0*' state.sls sls.nginx 4、客戶端驗證nginx是否安裝,啟動成功 salt 'salt0*' cmd.run 'rpm -qa|grep nginx' salt 'salt0*' cmd.run 'netstat -nltup|grep "8080"'

手動同步nginx配置文件

1、修改配置文件,將端口改為8080
    cat etc/nginx/conf.d/default.conf 
server {
    listen       8080 default_server;
2、使用salt同步配置文件,並重啟nginx(方法一)
    salt 'salt0*' state.sls sls.nginx
3、在minion端執行sls(方法二)
    salt-call state.sls sls.nginx
4、驗證minion的nginx配置文件是否同步成功,端口是否更改
    salt 'salt0*'  cmd.run 'netstat -nltup|grep "8080"'
5、定時同步方法:
   在minion端將salt-call state.sls sls.nginx 寫入到定時任務中去。

Pillar

Pillar是salt非常重要的一個組件,它用於給特定的minion定義任何你需要的數據,這些數據可以被salt的其它組件使用。Salt在0.98版本中引入了Pillar。

Pillar在解析完成后,是一個嵌套的字典結構;最上層的key是minion ID,其value是改minion所擁有的Pillar數據;每一個value也都是key:value。

這里可以看出一個特點,Pillar數據是與特定minion關聯的,也就是說每一個minion都只能看到自己的Pillar數據,所以可以用Pillar傳遞敏感數據(在salt的設計中,Pillar使用獨立的加密session,也是為了保證敏感數據的安全性)

Pillar使用場景

1、敏感數據:例如ssh-key,加密證書,由於Pillar使用獨立的加密session,可以確保這些敏感數據不給其它minion看到;

2、變量:可以在Pillar中處理平台差異性,比如針對不同的操作系統設置軟件包的名字,然后在State中使用;

3、其它任何數據:可以在Pillar中添加任何需要用到的數據。比如定義用戶和UID的對應關系,minion的角色等等;

4、target中:Pillar可以用來選擇minion,使用-l選項。默認情況下,master的配置文件中的所有數據都添加到Pillar中,且對所有minion可用。如果要禁用這一默認值,可以在master配置文件中添加如下數據,重啟服務后生效;

Pillar示例

官網地址:http://docs.saltstack.cn/topics/jobs/index.html

1、修改master配置文件
     vim /etc/salt/master
pillar_roots:
  base:
    - /srv/pillar
2、創建top.sls
    cat top.sls 
base:
  '*':
    - 'nginx.nginx'
3、創建nginx.sls
    cat nginx/nginx.sls 
schedule:
  test:
    function: state.sls
    minutes: 3600
    args:
      - 'nginx.nginx'
4、查看目錄結構
    tree pillar/
pillar/
├── nginx
│   └── nginx.sls
└── top.sls
5、下發pillar數據
    salt 'salt0*' pillar.data
6、刷新pillar數據
   salt 'salt0*'  saltutil.refresh_pillar
7、驗證端口,是否更新
    salt 'salt0*'  cmd.run 'netstat -lntup|grep -E ":80|:8080"'

Grains、Pillar區別:

Grains:靜態信息,客戶端的詳細信息,在minion端配置,與遠程執行走的近

Pillar:動態信息,客戶端的敏感詳細,在master端配置,安全,與配置管理走的近

 

Syndic(proxy代理master)

       master
      proxy           proxy
minion端 ............minion端

syndic接口是一個強大的工具,允許建立salt命令拓撲結構,salt的基本結構是一個salt master指揮一組salt minion,syndic接口是一種特殊的直通minion,它運行在一個master上且連接到另外一個master,然后syndic minion所連接的master就可以控制連接運行到syndic的master上的minion

1、代理機安裝salt-syndic
    yum install salt-maste
    yum install salt-syndic
2、修改配置文件
    vim /etc/salt/master
syndic_master: salt-master          更高級別master的IP地址
syndic_log_file: syndic                 日志文件的路徑(絕對路徑為佳)
order_masters:True                     確認轉發機制
3、啟動代理服務器
    /etc/init.d/salt-syndic  start

 

web管理頁面(halite)

安裝halite

 

方法一:失敗,待查原因

1、安裝並啟動salt-api

  • yum install salt-api –y
  • service salt-api start
  • chkconfig salt-api on

2、安裝halite及其依賴文件

  • yum install python-pip –y
  • pip install --upgrade pip
  • pip install -U halite
  • pip install cherrypy
  • pip install paste
  • yum install python-devel gcc –y
  • pip install gevent
  • pip install pyopenssl
  • pip install tornado

創建登錄用戶

  • useradd   salt
  • echo "salt" |passwd --stdin salt

3、修改master配置文件

 

 

方法二:

#yum install git

下載代碼

#cd /var/www

#git clone https://github.com/saltstack/halite

生成index.html

# cd halite/halite # ./genindex.py -C 

安裝salt-api

# yum install salt-api 

添加登陸用戶

# useradd salt # echo salt|passwd –stdin salt 

配置salt master文件

配置salt的master文件,添加:

rest_cherrypy: host: 0.0.0.0 port: 8080 debug: true static: /root/halite/halite app: /root/halite/halite/index.html 
external_auth: pam: salt: - .* - '@runner' - '@wheel' 

重啟master;

# /etc/init.d/salt-master restart 

啟動 salt-api,啟動web界面(兩種啟動方式)

#cd /var/www/halite/halite
(1)#nohup python2.6 server_bottle.py -d -C -l debug -s cherrypy &       #不使用nohup的話為前台運行

(2)# salt-api –d   ---后台運行

然后打開http://ip:8080/app,通過salt/salt登陸即可。

  

官方安裝教程:

https://docs.saltstack.com/en/latest/topics/tutorials/halite.htm

 參考博客:https://www.cnblogs.com/snailshadow

 

 

 

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM